@JmsListener 用于发布-订阅主题
@JmsListener usage for publish-subscribe topic
我正在尝试创建基于@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) {
//....
}
}
问题是得到这个行为:
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
时,它使用扩展 JmsDestinationAccessor
的 DefaultMessageListenerContainer
,默认情况下 pubSubDomain
设置为 false
。当此 属性 为 false 时,它正在队列上运行。如果您想使用主题,您必须将此属性值设置为 true
。
当您使用 Spring Boot 时,您可以通过将 spring.jms.pub-sub-domain
属性 添加到 application.properties
并设置它来轻松地将此 属性 设置为 true至 true
.
spring.jms.pub-sub-domain=true
当使用 @JmsListener
时,它正在寻找一个 jmsListenerContainerFactory
命名的 bean,如果它不可用,则需要一个默认的 bean。您还可以包含自己的 bean 并以编程方式设置此 属性 哟 true
.
@Bean
public DefaultMessageListenerContainer jmsListenerContainerFactory() {
DefaultMessageListenerContainer dmlc = new DefaultMessageListenerContainer();
dmlc.setPubSubDomain(true);
// Other configuration here
return dmlc;
}
这当然也有效,但会更有效,有关此的更多信息可以在 @EnableJms
annotation.
的文档中找到
将 @JmsListener
的默认目标类型从 Queue
切换到 Topic
完全可以在 Java 中完成,无需修改属性或使用 XML .
Spring guide 包含自定义 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;
}
然后可以在 @JmsListener
注释方法中使用:
@JmsListener(destination = "mailbox", containerFactory = "myFactory")
public void receiveMessage(Email email) {
// implementation
}
我正在尝试创建基于@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) {
//....
}
}
问题是得到这个行为:
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
时,它使用扩展 JmsDestinationAccessor
的 DefaultMessageListenerContainer
,默认情况下 pubSubDomain
设置为 false
。当此 属性 为 false 时,它正在队列上运行。如果您想使用主题,您必须将此属性值设置为 true
。
当您使用 Spring Boot 时,您可以通过将 spring.jms.pub-sub-domain
属性 添加到 application.properties
并设置它来轻松地将此 属性 设置为 true至 true
.
spring.jms.pub-sub-domain=true
当使用 @JmsListener
时,它正在寻找一个 jmsListenerContainerFactory
命名的 bean,如果它不可用,则需要一个默认的 bean。您还可以包含自己的 bean 并以编程方式设置此 属性 哟 true
.
@Bean
public DefaultMessageListenerContainer jmsListenerContainerFactory() {
DefaultMessageListenerContainer dmlc = new DefaultMessageListenerContainer();
dmlc.setPubSubDomain(true);
// Other configuration here
return dmlc;
}
这当然也有效,但会更有效,有关此的更多信息可以在 @EnableJms
annotation.
将 @JmsListener
的默认目标类型从 Queue
切换到 Topic
完全可以在 Java 中完成,无需修改属性或使用 XML .
Spring guide 包含自定义 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;
}
然后可以在 @JmsListener
注释方法中使用:
@JmsListener(destination = "mailbox", containerFactory = "myFactory")
public void receiveMessage(Email email) {
// implementation
}