【问题标题】:Spring Boot multiple JMS connectionsSpring Boot 多个 JMS 连接
【发布时间】:2018-09-06 07:21:49
【问题描述】:

我正在开发 Spring Boot 应用程序,该应用程序必须连接到具有不同端口甚至 IP 地址的多个 WebSphere JMS 连接。我需要接收和发送消息到不同的队列。

我以这个来源的连接为例 - https://github.com/lzp4ever/IBM_WebSphere_MQ_Spring_Boot_JMS

但是当我添加第二个connectionFactory时,Spring Boot无法启动,它只是不知道使用哪一次。

我的问题是我应该如何配置我的配置文件来监听多个队列?将 SpringBoot 应用程序连接到多个不同的 JMS 服务器是否是个好主意?

【问题讨论】:

  • “启动失败”信息不足;显示完整的错误消息,以及您的所有配置。拥有多个连接工厂很好,但您需要将所有内容正确连接在一起。

标签: java spring spring-boot jms spring-jms


【解决方案1】:

解决方案

我只是第二次复制并粘贴相同的 bean(如上面的 git 链接)并添加 Bean(name) 来分隔它们。它不起作用,然后我将新的 JmsListenerContainerFactory bean 添加到我的每个配置文件中。

我的一个配置文件是:

@Bean(name = "mqQueueConnectionFactory2")
public MQQueueConnectionFactory mqQueueConnectionFactory2() {
    MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
    mqQueueConnectionFactory.setHostName(host);
    try {
        mqQueueConnectionFactory.setTransportType(WMQConstants.WMQ_CM_CLIENT);
        mqQueueConnectionFactory.setCCSID(1208);
        mqQueueConnectionFactory.setChannel(channel);
        mqQueueConnectionFactory.setPort(port);
        mqQueueConnectionFactory.setQueueManager(queueManager);
    } catch (Exception e) {
        logger.error("MQQueueConnectionFactory bean exception", e);
    }
    return mqQueueConnectionFactory;
}

@Bean(name = "userCredentialsConnectionFactoryAdapter2")
UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter2(@Qualifier("mqQueueConnectionFactory2") MQQueueConnectionFactory mqQueueConnectionFactory) {
    UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter = new UserCredentialsConnectionFactoryAdapter();
    userCredentialsConnectionFactoryAdapter.setUsername(username);
    userCredentialsConnectionFactoryAdapter.setPassword(password);
    userCredentialsConnectionFactoryAdapter.setTargetConnectionFactory(mqQueueConnectionFactory);
    return userCredentialsConnectionFactoryAdapter;
}

@Bean(name = "cachingConnectionFactory2")
//@Primary
public CachingConnectionFactory cachingConnectionFactory2(@Qualifier("userCredentialsConnectionFactoryAdapter2") UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter) {
    CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
    cachingConnectionFactory.setTargetConnectionFactory(userCredentialsConnectionFactoryAdapter);
    cachingConnectionFactory.setSessionCacheSize(500);
    cachingConnectionFactory.setReconnectOnException(true);
    return cachingConnectionFactory;
}

@Bean(name = "jmsTransactionManager2")
public PlatformTransactionManager jmsTransactionManager2(@Qualifier("cachingConnectionFactory2") CachingConnectionFactory cachingConnectionFactory) {
    JmsTransactionManager jmsTransactionManager = new JmsTransactionManager();
    jmsTransactionManager.setConnectionFactory(cachingConnectionFactory);
    return jmsTransactionManager;
}

@Bean(name = "jmsOperations2")
public JmsOperations jmsOperations2(@Qualifier("cachingConnectionFactory2") CachingConnectionFactory cachingConnectionFactory) {
    JmsTemplate jmsTemplate = new JmsTemplate(cachingConnectionFactory);
    jmsTemplate.setReceiveTimeout(receiveTimeout);
    return jmsTemplate;
}

@Bean
public JmsListenerContainerFactory<?> myFactory2(@Qualifier("cachingConnectionFactory2") CachingConnectionFactory connectionFactory,
                                                 DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    // 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;
}

然后我从这里更改我的发件人代码:

@Autowired
private JmsOperations jmsOperations;

到这里

@Autowired
@Qualifier("jmsOperations2")
private JmsOperations jmsOperations;

我也将我的接收器更改为:

@JmsListener(destination = "${project.queues.uzb.recieve}", containerFactory = "myFactory2")
public void receiveMessage(JMSTextMessage data) {
    
}

在我看来它成功了!!!

但我的 CachingConnectionFactory 之一必须标记为 @Primary。如果我从我的一个配置文件中删除@Primaty,那么我就会遇到这个错误:

启动 ApplicationContext 时出错。要显示条件报告,请在启用“调试”的情况下重新运行您的应用程序。 2018-03-28 12:28:37 -


应用程序启动失败


说明:

com.config.UzbConnection 中方法 myFactory 的参数 1 需要一个找不到的 'org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer' 类型的 bean。

行动:

考虑在你的配置中定义一个“org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer”类型的bean。

谢谢

【讨论】:

    【解决方案2】:

    只有我的 2 美分。如果你有多个 JMS 连接的问题,因为你有一个项目使用 Spring-boot 和 JMS 与 Spring xml 配置的混合来创建你的连接工厂,你可以在你的应用程序中禁用 spring-boot-jms 的自动启动:

     @SpringBootApplication(exclude = {JmsAutoConfiguration.class})
    

    这样你可以混合使用。

    【讨论】:

      猜你喜欢
      • 2019-02-13
      • 2019-05-19
      • 2022-01-07
      • 2020-09-13
      • 2014-11-16
      • 1970-01-01
      • 2018-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多