@JmsListener用于发布 - 订阅主题的用法

lub*_*nac 13 spring spring-jms

我正在尝试基于@JmsListener注释为发布 - 订阅创建示例:https://github.com/lkrnac/book-eiws-code-samples/tree/master/05-jms/0515-publish-subscribe

相关代码段:

@Slf4j
@SpringBootApplication
@EnableScheduling
public class JmsPublishSubscribeApplication {

    public static void main(String[] args) throws InterruptedException {
        SpringApplication.run(JmsPublishSubscribeApplication.class, args);
    }

    @Bean
    public ActiveMQTopic simpleTopic() {
        return new ActiveMQTopic("simpleTopic");
    }

}

@Component
public class SimpleMessageListener1 {

    @JmsListener(destination = "simpleTopic")
    public void readMessage(String message) {
      //....
    }

}

@Component
public class SimpleMessageListener2 {

    @JmsListener(destination = "simpleTopic")
    public void readMessage(String message) {
      //....
    }

}
Run Code Online (Sandbox Code Playgroud)

问题是得到这种行为:

2015-05-17 20:07:04.985  INFO 22983 --- [pool-1-thread-1] n.l.b.e.chapter05.SimpleMessageSender    : Sending message: simple message
2015-05-17 20:07:05.070  INFO 22983 --- [enerContainer-1] n.l.b.e.c.JmsPublishSubscribeApplication : Message Received: simple message via listener 2
2015-05-17 20:07:05.975  INFO 22983 --- [pool-1-thread-1] n.l.b.e.chapter05.SimpleMessageSender    : Sending message: simple message
2015-05-17 20:07:05.986  INFO 22983 --- [enerContainer-1] n.l.b.e.c.JmsPublishSubscribeApplication : Message Received: simple message via listener 1
2015-05-17 20:07:06.975  INFO 22983 --- [pool-1-thread-1] n.l.b.e.chapter05.SimpleMessageSender    : Sending message: simple message
2015-05-17 20:07:06.987  INFO 22983 --- [enerContainer-1] n.l.b.e.c.JmsPublishSubscribeApplication : Message Received: simple message via listener 2
2015-05-17 20:07:07.975  INFO 22983 --- [pool-1-thread-1] n.l.b.e.chapter05.SimpleMessageSender    : Sending message: simple message
2015-05-17 20:07:07.994  INFO 22983 --- [enerContainer-1] n.l.b.e.c.JmsPublishSubscribeApplication : Message Received: simple message via listener 1
Run Code Online (Sandbox Code Playgroud)

但是,每个消息都应该由两个侦听器根据主题的定义来使用.我错过了什么?

M. *_*num 29

当使用@JmsListener它时,它使用一个DefaultMessageListenerContainer扩展JmsDestinationAccessor,默认pubSubDomain设置为false.当此属性为false时,它将在队列上运行.如果要使用主题,则必须将此属性值设置为true.

在使用Spring Boot时,通过将spring.jms.pub-sub-domain属性添加到application.properties并将其设置为,可以非常轻松地将此属性设置为true true.

spring.jms.pub-sub-domain=true
Run Code Online (Sandbox Code Playgroud)

当使用@JmsListener它时,它正在寻找一个jmsListenerContainerFactory命名的bean,如果它不可用,则需要一个默认的bean.您还可以包含自己的bean并以编程方式设置此属性哟true.

@Bean
public DefaultMessageListenerContainer jmsListenerContainerFactory() {
    DefaultMessageListenerContainer dmlc = new DefaultMessageListenerContainer();
    dmlc.setPubSubDomain(true);
    // Other configuration here
    return dmlc;
}
Run Code Online (Sandbox Code Playgroud)

这当然也可以工作,但会有更多的工作,有关这方面的更多信息可以在@EnableJms注释的文档中找到.


小智 7

开关的默认目标类型@JmsListenerQueueTopic可以完全用Java实现,而无需修改属性或使用XML。

弹簧导包含用于自定义所提供的缺省设置的实例DefaultMessageListenerContainer

它需要定义一个自定义bean,如下所示:

@Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
                                                DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    // This provides all boot's default to this factory, including the message converter
    configurer.configure(factory, connectionFactory);
    // You could still override some of Boot's default if necessary.
    factory.setPubSubDomain(true);
    return factory;
}
Run Code Online (Sandbox Code Playgroud)

然后可以在带@JmsListener注释的方法中使用它:

@JmsListener(destination = "mailbox", containerFactory = "myFactory")
public void receiveMessage(Email email) {
    // implementation
}
Run Code Online (Sandbox Code Playgroud)

  • @DhirajGandhi 你可以这样做:`@JmsListener(destination = "${async.jms.queue.name}", ...` (2认同)