Spring JMS 编程侦听器端点和事务

Spring JMS programmatic listener endpoints and transactions

当我以编程方式注册 JMS 侦听器端点时,我不再拥有事务支持。

我将 TransactionAwareConnectionFactoryProxy 与 JDBC 数据源和 JMS 一起使用,它提供了像 JTA 那样的良好全局事务(1PC 全局 tx)。使用注释效果很好:

@JmsListener(containerFactory = "jmsQueueListenerContainerFactory", destination = "queue/exampleQueue")
@Transactional
public void onQueueMessage(Message message, Session session) {...}

但是对于编程端点注册,它不起作用。端点注册码:

@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
    registrar.setContainerFactory(jmsListenerContainerFactory());
    SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
    endpoint.setId("Oelieboeliwieli");
    endpoint.setDestination("queue/exampleQueue");
    endpoint.setMessageListener(new Consumer());
    registrar.registerEndpoint(endpoint);
}

听众只是:

@Transactional
public void onMessage(Message message) { ... }

这两种情况下的其他一切都是一样的。我的猜测是没有为处理全局事务的 onMessage() 方法生成代理。使用带注释的解决方案,我看到从 invokeWithinTransaction() 调用生成的代理。

知道如何以简单的方式做到这一点吗?

您正在手动创建 Consumer,因此该对象根本不是托管 bean。应用程序上下文没有理由(实际上也没有办法)处理 class 并为其创建代理。

无论创建消息侦听器的是什么,都应该采用托管 bean。鉴于您提供的代码,很难理解为什么您需要进行程序化注册,但这是一个完全不同的话题。