持久订阅的@JmsListener 问题

@JmsListener issue with durable subscription

我正在使用 Spring 的 @JmsListener (spring-jms-4.3.4.RELEASE.jar) 使用以下代码从 ActiveMQ 接收消息:

@Component
public class TopicSubscriber {
    @JmsListener(destination="xyz.topic1", subscription="xyz_topic_durable_subscription")
    public void send(Product product) {     
        System.out.println(" reveived message ***"+product);
    }
}

根据 Spring API 的文档(link 下面给出),上面的代码应该创建一个订阅名称为 xyz_topic_durable_subscription 的持久订阅:

http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jms/annotation/JmsListener.html#subscription--

但是,问题是上面的代码只创建了非持久订阅,我可以通过使用管理控制台监视 ActiveMQ 找到它(在下面添加了屏幕截图,寻找 'xyz.topic1' 'Active Non-Durable Topic Subscribers' 部分下的目的地)。

是否需要对代码进行任何更改才能实现持久订阅?

您还需要配置侦听器容器工厂为durable subscriptions创建容器。

您需要适当配置 ListenerContainerFactory:

@Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
                                                DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setPubSubDomain(true);
    factory.setSubscriptionDurable(true);
    factory.setClientId("jmsDemo");
    // This provides all boot's default to this factory, including the message converter
    configurer.configure(factory, connectionFactory);
    // You could still override some of Boot's default if necessary.
    return factory;
}

有趣的部分在这里:

    factory.setSubscriptionDurable(true);
    factory.setClientId("jmsDemo");

现在,当您进入 ActiveMQ WebConsole 时,您应该会看到:

在上面标记为正确的答案中,代码:

factory.setPubSubDomain(true);
factory.setSubscriptionDurable(true);
factory.setClientId("jmsDemo");

必须在

之后
configurer.configure(factory, connectionFactory);

否则您将丢失这些设置。