Spring @发布订阅主题的JmsListener用法

Spring @发布订阅主题的JmsListener用法,spring,spring-jms,Spring,Spring Jms,我正在尝试创建基于@JmsListener注释的发布-订阅示例: 相关代码片段: @Slf4j @SpringBootApplication @EnableScheduling public class JmsPublishSubscribeApplication { public static void main(String[] args) throws InterruptedException { SpringApplication.run(JmsPublishS

我正在尝试创建基于@JmsListener注释的发布-订阅示例:

相关代码片段:

@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) {
      //....
    }

}
问题在于,要获得这种行为:

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

但每个消息都应该由两个侦听器根据主题的定义来使用。我缺少什么?

当使用
@JmsListener
时,它使用
DefaultMessageListenerContainer
,该容器默认扩展了
pubSubDomain
设置为
false
。当此属性为false时,它正在队列上操作。如果要使用主题,必须将此属性值设置为
true

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

spring.jms.pub-sub-domain=true
@Bean
public DefaultMessageListenerContainer jmsListenerContainerFactory() {
    DefaultMessageListenerContainer dmlc = new DefaultMessageListenerContainer();
    dmlc.setPubSubDomain(true);
    // Other configuration here
    return dmlc;
}
当使用时,它正在寻找
jmsListenerContainerFactory
命名的bean,如果该bean不可用,则需要一个默认bean。您还可以包括自己的bean,并通过编程将此属性设置为true

spring.jms.pub-sub-domain=true
@Bean
public DefaultMessageListenerContainer jmsListenerContainerFactory() {
    DefaultMessageListenerContainer dmlc = new DefaultMessageListenerContainer();
    dmlc.setPubSubDomain(true);
    // Other configuration here
    return dmlc;
}

这当然也会起作用,但会有更多的工作,有关这方面的更多信息可以在的文档中找到。

@JmsListener
的默认目标类型从
队列
切换到
主题
完全可以在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;
}

添加
application.properties
并将
spring.jms.pub子域
设置为
true
。可以确认此标志有效。奇怪的是,当您以编程方式执行时,它不起作用:jmsTemplate.setPubSubDomain(true)@M.Deinum难道你不想创建一个答案来获得一些分数吗?它也可以通过编程方式工作,但不能与
JmsTemplate一起使用,因为
@JmsListener
不使用它。您必须注册名为
jmsListenerContainer
DefaultMessageListenerContainer
,并将该属性设置为
true
。不过,简单地添加配置参数更容易。@M.Deinum您的建议不适用;对我来说不起作用,但名为“jmsListenerContainerFactory”的ldz worksBean的通知应为“org.springframework.jms.config.jmsListenerContainerFactory”类型,但实际上为“org.springframework.jms.listener.DefaultMessageListenerContainer”类型。我希望将参数destination和containerFactory作为非常量字段。如何使用注释实现这一点?请help@DhirajGandhi您可以这样做:
@JmsListener(destination=“${async.jms.queue.name}”,…