Java 在不阻塞主线程的情况下启动JMSListener

Java 在不阻塞主线程的情况下启动JMSListener,java,spring-boot,spring-jms,Java,Spring Boot,Spring Jms,我试图用spring boot启动一个应用程序,它有一个JMSListener连接到外部ActiveMQ,即使ActiveMQ关闭,这个应用程序也需要启动 我在连接中使用了故障转移传输协议,但是当我启动应用程序时,当JMS尝试建立连接时,主线程被阻塞,并且应用程序在第一次连接建立之前不会启动 我正在尝试这个解决方案,在这里我扩展了DefaultMessageListenerContainer并重写start方法,以在一个新线程中运行,该线程将释放主线程 Consumer.java public

我试图用spring boot启动一个应用程序,它有一个JMSListener连接到外部ActiveMQ,即使ActiveMQ关闭,这个应用程序也需要启动

我在连接中使用了故障转移传输协议,但是当我启动应用程序时,当JMS尝试建立连接时,主线程被阻塞,并且应用程序在第一次连接建立之前不会启动

我正在尝试这个解决方案,在这里我扩展了DefaultMessageListenerContainer并重写start方法,以在一个新线程中运行,该线程将释放主线程

Consumer.java

public class MyListenerContainerFactory extends DefaultJmsListenerContainerFactory {

    @Override
    protected DefaultMessageListenerContainer createContainerInstance() {
        return new MyListenerContainer();
    }
}
@springboot应用程序
公共类消费者{
公共静态void main(字符串[]args){
SpringApplication.run(Consumer.class,args);
System.out.println(“用户启动”);
}
}
接收器

@组件
公共类接收器{
@豆子
公共JmsListenerContainerFactory myFactory(连接工厂连接工厂,
DefaultJmsListenerContainerFactoryConfigurer(配置器){
DefaultJmsListenerContainerFactory=new MyListenerContainerFactory();
configurer.configure(工厂、连接工厂);
返回工厂;
}
@JmsListener(destination=“mailbox”,containerFactory=“myFactory”)
public void receiveMessage(字符串电子邮件){
系统输出打印项次(“收到”);
}
}
MyListenerContainer.java

public class MyListenerContainerFactory extends DefaultJmsListenerContainerFactory {

    @Override
    protected DefaultMessageListenerContainer createContainerInstance() {
        return new MyListenerContainer();
    }
}
公共类MyListenerContainer扩展了DefaultMessageListenerContainer{
@凌驾
public void start()引发JmsException{
新线程(()->{
super.start();
}).start();
}
}
MyListenerContainerFactory.java

public class MyListenerContainerFactory extends DefaultJmsListenerContainerFactory {

    @Override
    protected DefaultMessageListenerContainer createContainerInstance() {
        return new MyListenerContainer();
    }
}
1º问题: 这个解决方案是可行的,但我不确定这是否在Springbeans的开始阶段没有中断任何东西,因为我在创建连接之前完成了start方法。这会破坏SpringBoot中的bean创建过程吗

2º问题: 除此之外,如果我在同一个应用程序中有一个JMSListener和一个JMSProducer,它们将尝试使用相同的连接,还是使用不同的连接

如果有人有不同的更好的解决方案,请分享

谢谢你的时间和问候

贝尔纳多·内维斯

  • 使用
    factory.setAutoStart(false)可能更干净将阻止Spring尝试启动容器;准备好后(在任意线程上)使用container.start()
  • @Autowired
    私有JmsListenerEndpointRegistry注册表;
    ...
    registry.start();//启动所有容器
    //或
    registry.getListenerContainer(myContainerId.start();
    
  • 它们将使用相同的连接