Java Spring-JMS,如何在应用程序启动后启动JMS,并在应用程序停止时继续尝试重新连接

Java Spring-JMS,如何在应用程序启动后启动JMS,并在应用程序停止时继续尝试重新连接,java,spring,spring-jms,Java,Spring,Spring Jms,我有一个spring应用程序,我正在其中尝试连接到JMS activemq服务器。我的上下文文件内容如下所示: <bean id="amqPowerConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <constructor-arg index="0" value="${power.messagebrokerurl}"/> </bean> <bean

我有一个spring应用程序,我正在其中尝试连接到JMS activemq服务器。我的上下文文件内容如下所示:

<bean id="amqPowerConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
    <constructor-arg index="0" value="${power.messagebrokerurl}"/>
</bean>

<bean id="powerConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
    <constructor-arg ref="amqPowerConnectionFactory"/>
</bean>

<bean id="timeSeriesChangesContainer" class="org.springframework.jms.listener.SimpleMessageListenerContainer">
    <property name="connectionFactory" ref="powerConnectionFactory"/>
    <property name="destination" ref="powerEventQueue"/>
    <property name="messageListener" ref="timeSeriesDataAdapter"/>
</bean>

但如果JMS服务器关闭,则服务器不会在启动时初始化spring上下文

我可以将autoStartup设置为false,然后spring初始化上下文,但是如何手动启动这个侦听器呢

<bean id="timeSeriesChangesContainer" class="org.springframework.jms.listener.SimpleMessageListenerContainer">
    <property name="connectionFactory" ref="powerConnectionFactory"/>
    <property name="destination" ref="powerEventQueue"/>
    <property name="messageListener" ref="timeSeriesDataAdapter"/>
    <property name="autoStartup" value="false"/>
</bean>


此外,我还需要编写一个连续循环,如果JMS服务器出现故障,它将尝试重新连接到此JMS服务器。

消息侦听器有一个函数start()。 使用该函数,您可以在程序中手动启动侦听器

至于循环:我们有一个类似的问题,由于系统组件的不可用,我们必须在给定的时间启动和停止侦听器,我们通过预定的作业实现了这一点

下面是通过计划作业启动侦听器的示例:

更新:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class StartStopJmsBatch {

private static final Logger LOG = LoggerFactory.getLogger(StartStopJmsBatch.class);

@Autowired
private DefaultMessageListenerContainer messageListenerContainer;

@Scheduled(cron = "0 0 * * * *")
public void startJmsConsumer() {
    if (!messageListenerContainer.isRunning()) {
        LOG.info("Started JmsListenerContainer");
        messageListenerContainer.start();
    }
}
}
我把全班的其他人都加进去了。 通过spring的调度机制进行调度(特别是第28.4章) 至于cron表达式语法

备选方案


另一种选择是使用Spring的DefaultMessageListenerContainer(),它内置了自恢复功能,即使JMS服务器在应用程序启动时不可用,也应该初始化Spring上下文。

感谢@Wuteb的回答,正如您所说,我最终从SimpleMessageListenerContainer切换到DefaultMessageListenerContainer,这样就不需要添加任何类(如上面所建议的StartStopJmsBatch),我们唯一需要添加的是

<bean id="timeSeriesChangesContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="powerConnectionFactory"/>
    <property name="destination" ref="powerEventQueue"/>
    <property name="messageListener" ref="timeSeriesDataAdapter"/>
    <property name="recoveryInterval" value="500"/>
</bean>


其中recoveryInterval指定恢复尝试之间的间隔,以毫秒为单位。

谢谢,请您提供更多关于(cron=“${cron.startjmsconsumer}”)的详细信息,以及您在哪里编写这个类(上面的代码基本上是)我更新了答案,请检查您是否需要更多信息,或者是否足够。我复制了您的类并将其放在我的工作区中,为bean保留。Spring上下文在服务器启动时初始化。JMS服务器仍处于关闭状态。现在我启动了JMS,我希望它在日志中显示“StartedjmsListenerContainer”信息,但它没有。我还缺什么吗?应用程序上下文中可能有任何条目吗?我仍然不确定(cron=“${cron.startjmsconsumer}”)角色?您需要添加到spring xml配置中(在第28.4章中指定),并且${cron.startjmsconsumer}是我们项目中由spring替换的占位符。在您的情况下,它应该是这样的:(cron=“0****”)该表达式将安排作业在每天的每个小时的顶部运行(我将答案中的占位符替换为实际值以避免进一步的误解),只是想确认一下,即使JMS服务器在应用程序启动时不可用,recoveryInterval是否也能为您工作。在查看代码“DefaultMessageListenerContainer”时,似乎没有这样实现。此外,从参考链接(第二节:使用DefaultMessageListenerContainer接收消息)获得了相同的确认。目前,我的代码是activemq-all-5.3.0-jar和spring3.2.7,但如果可以的话,我愿意进行任何升级。任何更新感谢。