active mq和spring jmstemplate如何正确关闭

时间:2015-10-22 17:01:00

标签: activemq spring-batch jmstemplate

对于某些上下文,我使用符合jsr的实现在Spring批处理中执行JMS读取器和编写器。我正在使用Spring批处理提供的JMSReader和JMS编写器类,但我将它们包装在我自己的读写器中。 由于我使用的是JSR方法,因此我没有可用的典型应用程序上下文。根据jsr规范,通过作业规范或batch.xml初始化类。

我遇到的问题是我有一个独立的批处理应用程序,当我定义一个JMS读取器和/或jms编写器为活动mq创建连接工厂并将其设置为spring的JMSTemplate类的目标工厂时,应用程序完成处理后没有正常关闭。使用IBM MQ连接工厂的替代工作正常。

让我提供一些我已经完成的代码。

这是我创建连接工厂的地方。我做了几个注释的变化,试图让应用程序中的线程保持活动状态。

private ConnectionFactory openAMQ() throws IllegalArgumentException{
    ActiveMQConnectionFactory targetConnectionFactory = new ActiveMQConnectionFactory();

    if(protocol == null){
        throw new IllegalArgumentException("Active MQ protocol can not be empty");
    }

    AMQProtocols proto = AMQProtocols.valueOf(protocol.toUpperCase());

    StringBuilder sb = new StringBuilder();

    sb.append(proto.getProtocol()).append("://").append(this.host).append(":").append(this.port);

    if(amqParams != null && amqParams.trim().length() > 0){
        sb.append("?").append(amqParams);
    }

    targetConnectionFactory.setBrokerURL(sb.toString());
    //targetConnectionFactory.setAlwaysSessionAsync(false);
    //targetConnectionFactory.setUseAsyncSend(false);
    return targetConnectionFactory;
}

这是我创建JMSTemplate对象的地方

protected JmsTemplate getJMSTemplate(ConnectionFactory targetConnectionFactory){
    CachingConnectionFactory ccf = new CachingConnectionFactory();

    ccf.setTargetConnectionFactory(targetConnectionFactory);
    JmsTemplate template = new JmsTemplate(ccf);

    template.setDefaultDestinationName(jmsDefaultDestinationName);

    template.setReceiveTimeout(Long.parseLong(jmsReceiveTimeoutValue));
    template.setSessionTransacted(Boolean.parseBoolean(jmsSessionTransacted));
    //template.setMessageConverter(messageConverter);


    return template;
}

最后这里是JMSReader的开放方法,作者几乎完全相同

public void open(Serializable checkpoint) throws Exception {

    //First we need to get our broker specific connection factory
    ConnectionFactory targetConnectionFactory = getTargetConnectionFactory();

    this.template = getJMSTemplate(targetConnectionFactory);

    reader = new JmsItemReader();
    reader.setItemType(Class.forName(jmsItemTypeFullyQualifiedName));
    reader.setJmsTemplate(template);

}

我看到的线程似乎与连接以及一些不活动监视线程有关。随着它们保持活力,它会阻止独立应用程序关闭。

有没有人知道我如何配置连接工厂或jms模板来阻止这种情况发生,或者可能在读者完成后管理它以使其正常关闭。

1 个答案:

答案 0 :(得分:0)

我想我回答了自己的问题。在CachingConnectionFactory上,我在jms read和writer的close方法中添加了对destroy方法的调用。我确实有一些担心,调用它不允许正确清理,但它允许应用程序关闭而不是挂起。