Использование @JmsListener для темы публикация-подписка



Я пытаюсь создать пример для публикации-подписки на основе аннотации @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


Но каждое сообщение должно быть поглощено обоими слушателями по определению тем. Чего мне не хватает?
609   2  

2 ответов:

При использовании @JmsListener он использует DefaultMessageListenerContainer, который расширяет JmsDestinationAccessor который по умолчанию имеет значение pubSubDomain false. Если это свойство имеет значение false, оно работает с очередью. Если вы хотите использовать темы, вы должны установить это значение свойств в true.

Поскольку вы используете Spring Boot, вы можете довольно легко установить это свойство в true, добавив СВОЙСТВО spring.jms.pub-sub-domain к свойству application.properties и установив его в true.

spring.jms.pub-sub-domain=true

При использовании @JmsListener он ищет jmsListenerContainerFactory по имени бин, если это не доступно, ожидается, что по умолчанию. Вы также можете включить свой собственный Боб и программно задать это свойство yo true.

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

Это, конечно, тоже будет работать, но будет больше работы, более подробную информацию об этом можно найти в документации @EnableJms аннотация .

Переключение типа назначения по умолчанию @JmsListener из Queue в Topic может быть полностью выполнено в Java без изменения свойств или использования XML.

Пружинная направляющаясодержит пример настройки параметров по умолчанию, предоставляемых DefaultMessageListenerContainer.

Для этого требуется определить пользовательский Боб следующим образом:

@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
}

Comments

    Ничего не найдено.