Spring 4.1 @JmsListener配置

时间:2014-09-17 20:38:55

标签: spring spring-annotations spring-jms

我想将Spring 4.1中提供的新注释和功能用于需要JMS侦听器的应用程序。

我仔细阅读了Spring 4.1 JMS improvements post中的注释,但我仍然错过了@JmsListenerDestinationResolver之间的关系,以及我如何设置应用程序来表明正确{ {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指定相应队列名称的任何提示?

3 个答案:

答案 0 :(得分:15)

另请注意,根据用例,您已经可以使用每个环境的属性文件和PropertySourcesPlaceholderConfigurer进行参数化

@JmsListener(destinations = "${some.key}")

根据https://jira.spring.io/browse/SPR-12289

答案 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

相关问题