[英]Proper ultimate way to migrate JMS event listening to Spring Integration with Spring Boot
I got a JmsConfig
configuration class that handles JMS events from a topic in the following way: 我得到了一个
JmsConfig
配置类,该配置类以以下方式处理主题的JMS事件:
@Bean ConnectionFactory
, containing an ActiveMQ implementation @Bean ConnectionFactory
,其中包含一个ActiveMQ实现。 @Bean JmsListenerContainerFactory
instantiating a DefaultJmsListenerContainerFactory
and passing it through Boot's DefaultJmsListenerContainerFactoryConfigurer
@Bean JmsListenerContainerFactory
实例化DefaultJmsListenerContainerFactory
并将其通过Boot的DefaultJmsListenerContainerFactoryConfigurer
@Bean MessageConverter
containing a MappingJackson2MessageConverter
and setting a custom ObjectMapper
@Bean MessageConverter
其中包含一个MappingJackson2MessageConverter
并设置了一个自定义ObjectMapper
@JmsListener
annotation pointing to myfactory on a method of my service. @JmsListener
注释指向myfactory。 This is the only use I have for the topic, subscription alone. Now I want to move to Spring Integration . 现在我想转向Spring Integration 。 After reading a lot, and provided I don't need a bidirectional use (discarding Gateways ) neither a polling mechanism (discarding
@InboundChannelAdapter
), I am going for a message-driven-channel-adapter
, in traditional XML configuration wording. 在阅读了很多书之后,并且假设我不需要双向使用(丢弃Gateway )和轮询机制(丢弃
@InboundChannelAdapter
),我将使用传统的XML配置文字中的message-driven-channel-adapter
。 I found that Java idiom should be accomplished by means of the new Spring Integration DSL library, and thus, I look for the proper snippet. 我发现Java习惯用法应该通过新的Spring Integration DSL库来完成,因此,我正在寻找适当的代码段。
It seems JmsMessageDrivenChannelAdapter
is the proper equivalent, and I found a way: 似乎
JmsMessageDrivenChannelAdapter
是适当的等效项,我找到了一种方法:
IntegrationFlows.from(Jms.messageDriverChannelAdapter(...))
But the problem is that this only accepts the ActiveMQ ConnectionFactory or an AbstractMessageListenerContainer
, but no my boot pre-configured JmsListenerContainerFactory
! 但是问题在于,这仅接受ActiveMQ ConnectionFactory或
AbstractMessageListenerContainer
,而不接受我的引导预先配置的JmsListenerContainerFactory
!
How should this be implemented in an ultimate way? 应该如何最终实现呢?
JmsListenerContainerFactory
is specific for the @JmsListener
, it's a higher level abstraction used to configure a DefaultMessageListenerContainer
. JmsListenerContainerFactory
专门用于@JmsListener
,它是用于配置DefaultMessageListenerContainer
的更高级别的抽象。 Boot does not provide an auto configuration option for a raw DefaultMessageListenerContainer
; 引导程序不为原始
DefaultMessageListenerContainer
提供自动配置选项; you have to wire it up yourself. 您必须自己连接。 But you can still use the Boot properties...
但是您仍然可以使用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;
}
There is even a better approach. 甚至有更好的方法。 I am surprised Gary did not comment it.
我很惊讶加里没有对此发表评论。 There's an out-of-the-box builder called
Jms.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.