Java 在Spring中在步骤之间传递信息?
我正在试着做一个春季批次,但我没有这方面的经验 是否可以传递每个批处理步骤的信息,或者它们必须完全独立 例如,如果我有Java 在Spring中在步骤之间传递信息?,java,spring,spring-batch,Java,Spring,Spring Batch,我正在试着做一个春季批次,但我没有这方面的经验 是否可以传递每个批处理步骤的信息,或者它们必须完全独立 例如,如果我有 <batch:step id="getSQLs" next="runSQLs"> <batch:tasklet transaction-manager="TransactionManager" ref="runGetSQLs" /> </batch:step> <batch
<batch:step id="getSQLs" next="runSQLs">
<batch:tasklet transaction-manager="TransactionManager"
ref="runGetSQLs" />
</batch:step>
<batch:step id="runSQLs">
<batch:tasklet transaction-manager="TransactionManager"
ref="runRunSQLs" />
</batch:step>
我是否需要以某种方式将stepExecution传递给execute方法?Spring Batch支持将数据推送到未来的作业步骤,这可以通过
ExecutionContext
完成,更准确地说是JobExecutionContext
。这里我指的是,因为它是我的终极参考:
为了使数据可用于未来的步骤,必须
步骤完成后,“升级”到作业执行上下文。
Spring批处理为此提供ExecutionContextPromotionListener
目的
侦听器应配置您的步骤,即与将来的步骤共享数据的步骤:
应从执行代码块中填充数据,如下所示:
/。。。
ExecutionContext stepContext=this.stepExecution.getExecutionContext();
放置(“列表键”,您的列表);
然后,在后续步骤中,可以使用带有@BeforeStep
a注释的post-computation钩子检索该列表,如下所示:
@BeforeStep
公共无效检索共享数据(步骤执行步骤执行){
JobExecution JobExecution=stepExecution.getJobExecution();
ExecutionContext jobContext=jobExecution.getExecutionContext();
this.myList=jobContext.get(“列表键”);
}
java配置方式
步骤1:配置ExecutionContextPromotionListener
@Bean
public ExecutionContextPromotionListener executionContextPromotionListener()
{
ExecutionContextPromotionListener executionContextPromotionListener = new ExecutionContextPromotionListener();
executionContextPromotionListener.setKeys(new String[] {"MY_KEY"});
return executionContextPromotionListener;
}
@BeforeStep
public void beforeStep(StepExecution stepExecution) {
jobExecutionContext = stepExecution.getJobExecution().getExecutionContext();
jobExecutionContext.getString("MY_KEY")
}
步骤2:使用ExecutionContextPromotionListener配置步骤
@豆子
public Step myStep() {
return stepBuilderFactory.get("myStep")
.<POJO, POJO> chunk(1000)
.reader(reader()
.processor(Processor())
.writer(Writer()
.listener(promotionListener())
.build();
}
步骤4:在处理器中设置数据
@BeforeStep
public void beforeStep(StepExecution stepExecution) {
stepExecution.getJobExecution().getExecutionContext().put("MY_KEY", My_value);
}
如果您想使用ExecutionContext在步骤之间传递信息,我建议您三思。通常这意味着工作设计得不完美。springbatch的主要思想是处理大量的数据。ExecutionContext用于存储有关作业/步骤进度的信息,以在出现故障时减少不必要的工作。在设计上,您无法将大数据放入ExecutionContext。在完成一个步骤后,您应该以可靠可读的形式获得信息—文件、数据库等。这些数据可以在后续步骤中用作输入。对于简单的作业,我建议只使用作业参数作为信息源
在您的例子中,“runGetSQLs”看起来不是一个很好的步骤候选,但是如果您愿意,您可以在“runsqls”步骤中将其实现为Springbean和autowire(这同样是一个很好的步骤候选)。根据您的命名,runGetSQLs看起来像ItemReader,runsqls看起来像itemrater。因此,它们是一个步骤的一部分,而不是不同的步骤。在这种情况下,您不需要将信息传输到其他步骤。我的代码似乎无法识别步骤执行。我导入了org.springframework.batch.core.StepExecution。我在这里遗漏了什么?你应该用你的代码块更新帖子,并提及你到目前为止所做的事情。我还更改了步骤以匹配您的示例。奇怪的是,从一个步骤到下一个步骤传递数据的最常见用例没有得到满足,而且您有一个奇怪的晋升到工作上下文解决方案。如果您有一个分区器,该分区器然后并行运行步骤,则此解决方案不起作用。@该分区器也会污染DBBATCH\u JOB\u EXECUTION\u CONTEXT。带有中间数据的序列化\u CONTEXT
不是最佳解决方案。在作业步骤之间传递数据的要求意味着您违反了批处理规则。谢谢,Niraj。这就是我所期待的。
@BeforeStep
public void beforeStep(StepExecution stepExecution) {
jobExecutionContext = stepExecution.getJobExecution().getExecutionContext();
jobExecutionContext.getString("MY_KEY")
}
@BeforeStep
public void beforeStep(StepExecution stepExecution) {
stepExecution.getJobExecution().getExecutionContext().put("MY_KEY", My_value);
}