Spring批处理文档建议使用JmsItemReader,它是JMSTemplate的包装器。但是,我发现JMSTemplate存在一些问题 - 请参阅http://activemq.apache.org/jmstemplate-gotchas.html。
这篇文章引起了我的注意,因为在我真正读取它的数据之前,队列似乎消失了。错过消息的机会对我来说似乎是一个相当重要的问题。
答案 0 :(得分:0)
对于消费者至少尝试使用DefaultMessageListenerContainer加上SingleConnectionFactory或任何此类连接工厂,它不需要调度程序来唤醒它们。这里有解释这个例子的日志,这个解释东西非常好 http://bsnyderblog.blogspot.com/2010/05/tuning-jms-message-consumption-in.html
答案 1 :(得分:0)
这是我最终解决的问题。由于查询是关于从弹簧批处理步骤中听取JMS的“最干净”的方式,因此我将打开问题一段时间,以防万一有更好的方法。
如果有人能弄清楚代码格式不正确的原因,请告诉我如何修复它。
<强> 1。在作业监听器中,分别在beforeJob和afterJob事件中实现队列设置和拆除:
public void beforeJob(JobExecution jobExecution) {
try {
jobParameters = jobExecution.getJobParameters();
readerConnection = connectionFactory.createConnection();
readerConnection.start();
} catch (JMSException ex) {
// handle the exception as appropriate
}
}
public void afterJob(JobExecution jobExecution) {
try {
readerConnection.close();
} catch (JMSException e) {
// handle the exception as appropriate
}
}
<强> 2。在阅读器中,实现StepListener和beforeStep / afterStep方法。
public void beforeStep(StepExecution stepExecution) {
this.stepExecution = stepExecution;
this.setJobExecution(stepExecution.getJobExecution());
try {
this.connection = jmsJobExecutionListener.getReaderConnection();
this.jmsSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
this.messageConsumer = jmsSession.createConsumer(jmsJobExecutionListener.getQueue());
}
catch (JMSException ex)
{
// handle the exception as appropriate
}
}
public ExitStatus afterStep(StepExecution stepExecution) {
try {
messageConsumer.close();
jmsSession.close();
} catch (JMSException e) {
// handle the exception as appropriate
}
return stepExecution.getExitStatus();
}
第3。实现read()方法:
public TreeModel<SelectedDataElementNode> read() throws Exception,
UnexpectedInputException, ParseException,
NonTransientResourceException {
Object result = null;
logger.debug("Attempting to receive message on connection: ", connection.toString());
ObjectMessage msg = (ObjectMessage) messageConsumer.receive();
logger.debug("Received: {}", msg.toString());
result = msg.getObject();
return result;
}
<强> 4。根据需要将侦听器添加到Spring Batch上下文:
<batch:job id="doStuff">
<batch:listeners>
<batch:listener ref="jmsJobExecutionListener" />
</batch:listeners>
... snip ...
<batch:step id="step0003-do-stuff">
<batch:tasklet transaction-manager="jtaTransactionManager"
start-limit="100">
<batch:chunk reader="selectedDataJmsReader" writer="someWriter"
commit-interval="1" />
</batch:tasklet>
<batch:listeners>
<batch:listener ref="selectedDataJmsReader" />
</batch:listeners>
</batch:step>
</batch:job>