对于某些上下文,我使用符合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模板来阻止这种情况发生,或者可能在读者完成后管理它以使其正常关闭。
答案 0 :(得分:0)
我想我回答了自己的问题。在CachingConnectionFactory上,我在jms read和writer的close方法中添加了对destroy方法的调用。我确实有一些担心,调用它不允许正确清理,但它允许应用程序关闭而不是挂起。