对于某些上下文,我正在使用符合 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 的 open 方法,作者几乎相同
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 模板以阻止这种情况发生,或者在阅读器完成后可能对其进行管理以使其正确关闭。