我想使用Spring 4.1中提供的新的注释和功能,用于需要JMS侦听器的应用程序.
我仔细阅读了Spring 4.1 JMS improvements post中的注释,但我仍然怀念@JmsListener和DestinationResolver之间的关系,以及如何设置应用程序来指示正确的Destination或Endpoint.
这是建议使用@JmsListener
@Component
public class MyService {
@JmsListener(containerFactory = "myContainerFactory",destination = "myQueue")
public void processOrder(String data) { ... }
}
现在,我不能在我的实际代码中使用这个,因为需要使用Environment.getProperty()从配置文件读取“myQueue”.
我可以使用DestinationResolver设置一个合适的myContainerFactory,但是大多数情况下,如果您不需要JNDI在应用服务器中查找队列,并且不需要执行一些自定义回复逻辑,那么您似乎只需使用DynamicDestinationResolver.我只是想了解Spring如何使用@JmsListener注释以参数化的方式来指示队列的名称.
@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在上面的代码中.
最佳答案
你最终可以这样做,但这有点复杂.您可以使用JmsListenerConfigurer设置自定义JmsListenerEndpointRegistry
@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