添加动态监听数(Spring JMS)

问题描述 投票:0回答:4

我需要添加

application.properties
文件中提到的多个监听器。喜欢下面,

InTopics=Sample.QUT4,Sample.T05,Sample.T01,Sample.JT7

注意:这个数字可以多也可以少。

我正在考虑把它们放在一个数组中,

@Value("${InTopics}")
private String[] inTopics;

但是我不知道如何从数组中创建多个监听器。

目前,对于我正在做的一个主题,

@Configuration
@EnableJms
public class JmsConfiguration {

@Value("${BrokerURL}")
private String brokerURL;

@Value("${BrokerUserName}")
private String brokerUserName;

@Value("${BrokerPassword}")
private String brokerPassword;

@Bean
TopicConnectionFactory connectionFactory() throws JMSException {
    TopicConnectionFactory connectionFactory = new TopicConnectionFactory(brokerURL, brokerUserName, brokerPassword);
    return connectionFactory;
}

@Bean
JmsListenerContainerFactory<?> jmsContainerFactory(TopicConnectionFactory connectionFactory) throws JMSException {
    SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    factory.setPubSubDomain(Boolean.TRUE);
    return factory;
 }

}

还有我的听众,

@JmsListener(destination = "${SingleTopicName}", containerFactory = "jmsContainerFactory")
public void receiveMessage(Message msg) {
   //Do Some Stuff
}

我有什么办法可以做到这一点吗?

java spring spring-boot jms spring-jms
4个回答
15
投票

你不能用带注释的

@JmsListener
s来做到这一点,但你可以通过扩展JmsListenerConfigurer
以编程方式注册每个监听器
,如参考文档
中所述。

编辑

因为您将属性作为数组注入...

@Value("${InTopics}")
private String[] inTopics;

Spring 将拆分列表并根据列表中的队列数创建一个数组。

然后您可以在

JmsListenerConfigurer.configureJmsListeners()
中遍历数组并为数组中的每个元素创建一个端点——您不需要提前知道数组有多大。

for (String inTopic : inTopics) {
    ...
}

0
投票

这里是动态定义监听器数量的自定义代码。

JmsConfiguration jmsConfiguration;

private List<String> queueList;

@Bean
public DefaultJmsListenerContainerFactory mqJmsListenerContainerFactory() throws JMSException {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(jmsConfiguration.jmsConnectionFactory());
    factory.setDestinationResolver(new DynamicDestinationResolver());
    factory.setSessionTransacted(true);
    factory.setConcurrency("5");
    return factory;
}

@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {

    queueList.forEach(queue -> {
        SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
        endpoint.setId(queue);
        endpoint.setDestination(queue);
        try {
            endpoint.setMessageListener(message -> {
                try {
                    logger.info("Receieved ID: {} Destination {}", message.getJMSMessageID(), message.getJMSDestination());
                }
                catch (JMSException e) {
                    logger.info("Exception while reading message - " + e);
                }
            });
            registrar.setContainerFactory(mqJmsListenerContainerFactory());
        }
        catch (JMSException e) {
            logger.info("Exception - " + e);
        }
        registrar.registerEndpoint(endpoint);
    });

}

0
投票

我不知道这是存在的,我不得不手动写下所有这些代码。因此,另一种方法是在您的 bean 中实现

BeanFactoryPostProcessor
并手动添加 jms 侦听器的所有必需组件。

  1. jndiTemplate
  2. jndiQueueConnectionFactory
    (取决于步骤 1 中的 jndiTemplate)
  3. queueConnectionFactory
    (取决于步骤 2 中的 jndiQueueConnectionFactory)
  4. jndiDestinationResolver
    (使用 stem 1 中的 jndiTemplate)
  5. messageListenerContiner
    (使用以上创建的所有项目)

所以,如您所见,我不仅增加了 jms 侦听器,而且还动态生成了多个侦听器容器。 Ofc,这是我的要求。并且可能会根据要求而有所不同。

要记住的一件事是,当您操作

BeanFactoryPostProcessor
时,没有资源(如属性等。加载)。您必须手动加载属性。我通过,
afterPropertiesSet
方法来自
InitializingBean


0
投票

我们能得到一些示例代码吗?我试过了,但对我不起作用。

© www.soinside.com 2019 - 2024. All rights reserved.