我想将Spring 4.1中提供的新注释和功能用于需要JMS侦听器的应用程序。
我仔细阅读了Spring 4.1 JMS improvements post中的注释,但我仍然错过了@JmsListener
和DestinationResolver
之间的关系,以及我如何设置应用程序来表明正确{ {1}}或Destination
。
以下是@JmsListener的建议用法
Endpoint
现在,我无法在实际代码中使用它,因为需要使用@Component
public class MyService {
@JmsListener(containerFactory = "myContainerFactory", destination = "myQueue")
public void processOrder(String data) { ... }
}
从配置文件中读取“myQueue”。
我可以使用Environment.getProperty()
设置合适的myContainerFactory,但大多数情况下,如果您不需要JNDI来查找应用服务器中的队列而不需要,那么您似乎只会使用DestinationResolver
做一些自定义回复逻辑。我只是想了解Spring如何使用DynamicDestinationResolver
注释以参数化方式指示队列的名称。
在博客文章的下方,我找到了对此配置器的引用:
@JmsListener
现在,这有点意义,我可以看到这将允许我在某些外部字符串中设置运行时的Destination,但这似乎与使用@Configuration
@EnableJms
public class AppConfig implements JmsListenerConfigurer {
@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
registrar.setDefaultContainerFactory(defaultContainerFactory());
SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
endpoint.setDestination("anotherQueue");
endpoint.setMessageListener(message -> {
// processing
});
registrar.registerEndpoint(endpoint);
}
相冲突,因为它似乎是在上面的代码中覆盖注释以支持@JmsListener
。
有关如何使用endpoint.setMessageListener
指定相应队列名称的任何提示?
答案 0 :(得分:15)
另请注意,根据用例,您已经可以使用每个环境的属性文件和PropertySourcesPlaceholderConfigurer进行参数化
@JmsListener(destinations = "${some.key}")
答案 1 :(得分:4)
如果人们使用@JmsListener
进行春季启动,则不必配置PropertySourcesPlaceholderConfigurer
。它开箱即用
示例:
<强>类强>
@JmsListener(destination = "${spring.activemq.queue.name}")
public void receiveEntityMessage(final TextMessage message) {
// process stuff
}
}
<强> application.properties 强>
spring.activemq.queue.name=some.weird.queue.name.that.does.not.exist
Spring启动输出
[26-Aug;15:07:53.475]-[INFO ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[931 ]-Successfully refreshed JMS Connection
[26-Aug;15:07:58.589]-[WARN ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[880 ]-Setup of JMS message listener invoker failed for destination 'some.weird.queue.name.that.does.not.exist' - trying to recover. Cause: User user is not authorized to read from some.weird.queue.name.that.does.not.exist
[26-Aug;15:07:59.787]-[INFO ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[931 ]-Successfully refreshed JMS Connection
[26-Aug;15:08:04.881]-[WARN ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[880 ]-Setup of JMS message listener invoker failed for destination 'some.weird.queue.name.that.does.not.exist' - trying to recover. Cause: User user is not authorized to read from some.weird.queue.name.that.does.not.exist
这证明@JmsListener能够从application.properties中获取属性值,而无需实际设置任何显式PropertySourcesPlaceholderConfigurer
我希望这有帮助!
答案 2 :(得分:2)
你现在最终可以做到这一点,但它有点复杂。您可以使用JmsListenerEndpointRegistry
JmsListenerConfigurer
@Configuration
@EnableJms
public class AppConfig implements JmsListenerConfigurer {
@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
registrar.setEndpointRegistry(customRegistry());
}
}
然后覆盖registerListenerContainer方法,类似于
public void registerListenerContainer(JmsListenerEndpoint endpoint, JmsListenerContainerFactory<?> factory) {
// resolve destination according to whatever -> resolvedDestination
((AbstractJmsListenerEndpoint)endpoint).setDestination(resolvedDestination);
super.registerListenerContainer(endpoint, factory);
}
但我们可以做得更好。请观看/投票SPR-12280