簡體   English   中英

遷移JMS事件以偵聽Spring Boot with Spring Boot的正確最終方法

[英]Proper ultimate way to migrate JMS event listening to Spring Integration with Spring Boot

我得到了一個JmsConfig配置類,該配置類以以下方式處理主題的JMS事件:

  • 它定義了一個@Bean ConnectionFactory ,其中包含一個ActiveMQ實現。
  • 它定義一個@Bean JmsListenerContainerFactory實例化DefaultJmsListenerContainerFactory並將其通過Boot的DefaultJmsListenerContainerFactoryConfigurer
  • 它定義了一個@Bean MessageConverter其中包含一個MappingJackson2MessageConverter並設置了一個自定義ObjectMapper
  • 我在服務的方法上使用@JmsListener注釋指向myfactory。 這是我僅對訂閱有此主題的唯一用途。

現在我想轉向Spring Integration 在閱讀了很多書之后,並且假設我不需要雙向使用(丟棄Gateway )和輪詢機制(丟棄@InboundChannelAdapter ),我將使用傳統的XML配置文字中的message-driven-channel-adapter 我發現Java習慣用法應該通過新的Spring Integration DSL庫來完成,因此,我正在尋找適當的代碼段。

似乎JmsMessageDrivenChannelAdapter是適當的等效項,我找到了一種方法:

IntegrationFlows.from(Jms.messageDriverChannelAdapter(...))

但是問題在於,這僅接受ActiveMQ ConnectionFactory或AbstractMessageListenerContainer ,而不接受我的引導預先配置的JmsListenerContainerFactory

應該如何最終實現呢?

JmsListenerContainerFactory專門用於@JmsListener ,它是用於配置DefaultMessageListenerContainer的更高級別的抽象。 引導程序不為原始DefaultMessageListenerContainer提供自動配置選項; 您必須自己連接。 但是您仍然可以使用Boot屬性...

@Bean
public IntegrationFlow flow(ConnectionFactory connectionFactory, 
                            JmsProperties properties) {
    return IntegrationFlows.from(Jms.messageDrivenChannelAdapter(container(connectionFactory, properties)))
            ...
            .get();
}

private DefaultMessageListenerContainer container(ConnectionFactory connectionFactory, 
                                                  JmsProperties properties) {
    DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
    container.setConcurrentConsumers(properties.getListener().getConcurrency());
    container.setMaxConcurrentConsumers(properties.getListener().getMaxConcurrency());
    ...
    return container;
}

甚至有更好的方法。 我很驚訝加里沒有對此發表評論。 有一個開箱即用的生成器,名為Jms.container(...)

@Bean
public IntegrationFlow jmsMyServiceMsgInboundFlow(ConnectionFactory connectionFactory, MessageConverter jmsMessageConverter, MyService myService, JmsProperties jmsProperties, @Value("${mycompany.jms.destination.my-topic}") String topicDestination){

      JmsProperties.Listener jmsInProps = jmsProperties.getListener();

      return IntegrationFlows.from(
                                Jms.messageDrivenChannelAdapter(  Jms.container(connectionFactory, topicDestination)
                                                                     .pubSubDomain(false)
                                                                     .sessionAcknowledgeMode(jmsInProps .getAcknowledgeMode().getMode())
                                                                     .maxMessagesPerTask(1)
                                                                     .errorHandler(e -> e.printStackTrace())
                                                                     .cacheLevel(0)
                                                                     .concurrency(jmsInProps.formatConcurrency())
                                                                     .taskExecutor(Executors.newCachedThreadPool())
                                                                     .get()))
                                   )
                                   .extractPayload(true)
                                   .jmsMessageConverter(jmsMessageConverter)
                                   .destination(topicDestination)
                                   .autoStartup(true)
                                    //.errorChannel("NOPE")
                             )
                             .log(LoggingHandler.Level.DEBUG)
                             .log()
                             .handle(myService, "myMethod", e -> e.async(true).advice(retryAdvice()))
                             .get();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM