简体   繁体   English

Spring Boot 多个 JMS 连接

[英]Spring Boot multiple JMS connections

I'm developing Spring Boot application which must connect to several WebSphere JMS connections with different ports or even ip addresses.我正在开发 Spring Boot 应用程序,它必须连接到具有不同端口甚至 IP 地址的多个 WebSphere JMS 连接。 I need receive and send messages to different queues.我需要接收和发送消息到不同的队列。

I took example of connection from this source - https://github.com/lzp4ever/IBM_WebSphere_MQ_Spring_Boot_JMS我从这个源中获取了连接示例 - https://github.com/lzp4ever/IBM_WebSphere_MQ_Spring_Boot_JMS

But when i add second connectionFactory Spring Boot failes to start, it just don't know which once to use.但是当我添加第二个 connectionFactory Spring Boot 无法启动时,它只是不知道使用哪个一次。

My question is How should i configure my config file to listen several queues?我的问题是我应该如何配置我的配置文件来监听多个队列? Is it good idea connecting SpringBoot app to several different JMS servers?将 SpringBoot 应用程序连接到几个不同的 JMS 服务器是个好主意吗?

Solution解决方案

i just copy and paste same beans(like at git link above) second time and add Bean(name) to separate them.我只是第二次复制并粘贴相同的 bean(如上面的 git 链接)并添加 Bean(name) 以将它们分开。 It was not work and then i added new JmsListenerContainerFactory bean to each of my config file.它不起作用,然后我将新的 JmsListenerContainerFactory bean 添加到我的每个配置文件中。

One of my config file is:我的配置文件之一是:

@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;
}

Then i change my sender code from this:然后我从这个更改我的发件人代码:

@Autowired
private JmsOperations jmsOperations;

to this对此

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

also i change my receiver to:我也将接收器更改为:

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

it seems to me it worked!!!在我看来它奏效了!!!

But one of my CachingConnectionFactory must be marked as @Primary.但是我的 CachingConnectionFactory 之一必须标记为@Primary。 If i delete @Primaty from one of my config files then i am gettig this error:如果我从我的配置文件之一中删除 @Primaty,那么我就会收到此错误:

Error starting ApplicationContext.启动 ApplicationContext 时出错。 To display the conditions report re-run your application with 'debug' enabled.要显示条件报告,请在启用“调试”的情况下重新运行您的应用程序。 2018-03-28 12:28:37 - 2018-03-28 12:28:37 -


APPLICATION FAILED TO START应用程序无法启动


Description:说明:

Parameter 1 of method myFactory in com.config.UzbConnection required a bean of type 'org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer' that could not be found. com.config.UzbConnection 中方法 myFactory 的参数 1 需要一个无法找到的“org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer”类型的 bean。

Action:行动:

Consider defining a bean of type 'org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer' in your configuration.考虑在您的配置中定义一个 'org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer' 类型的 bean。

Thanks谢谢

Just my 2 cents.只有我的 2 美分。 If you have problems with multiple JMS connections because you have a project using a mix of Spring-boot and JMS with Spring xml configuration to make your connection factory, you can disable autostart of spring-boot-jms with this in your application:如果您有多个 JMS 连接的问题,因为您有一个项目使用 Spring-boot 和 JMS 的混合配置以及 Spring xml 配置来创建连接工厂,您可以在应用程序中禁用 spring-boot-jms 的自动启动:

 @SpringBootApplication(exclude = {JmsAutoConfiguration.class})

this way you can mix both.这样你就可以混合两者。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM