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

我已经仔细阅读了Spring 4.1 JMS improvements post中的注释,但是我仍然想念@JmsListenerDestinationResolver之间的关系,以及如何设置应用程序以指示正确的DestinationEndpoint

这是@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在上面的代码中。

关于如何使用@JmsListener指定适当的队列名称的任何技巧?

最佳答案

您最终可以立即执行此操作,但这有点令人费解。您可以使用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

09-28 02:46