我正在尝试制作一个Spring 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>
getSQLs触发一个bean,它执行一个生成List类型String的类。是否可以引用runSQLs触发的bean列表? (“触发”可能不是正确的术语,但我想你知道我的意思)
更新: 所以getSQLs步骤会触发这个bean:
<bean id="runGetSQLs" class="myTask"
scope="step">
<property name="filePath" value="C:\Users\username\Desktop\sample.txt" />
</bean>
触发执行此方法的myTask类:
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
ExecutionContext stepContext = this.stepExecution.getExecutionContext();
stepContext.put("theListKey", sourceQueries);
return RepeatStatus.FINISHED;
}
我是否需要以某种方式将stepExecution传递给execute方法?
答案 0 :(得分:9)
Spring Batch支持将数据推送到未来的工作步骤,这可以通过ExecutionContext
完成,更准确地说是JobExecutionContext
。在这里,我指的是example from the official documentation,因为它是我的最终参考:
要使数据可用于未来的步骤,必须如此 &#34;促进&#34;步骤完成后到Job ExecutionContext。 Spring Batch为此提供ExecutionContextPromotionListener 目的
应该使用您的步骤配置监听器,该步骤与未来的数据共享数据:
<batch:step id="getSQLs" next="runSQLs">
<batch:tasklet transaction-manager="TransactionManager"
ref="runGetSQLs" />
<listeners>
<listener>
<beans:bean id="promotionListener" class="org.springframework.batch.core.listener.ExecutionContextPromotionListener">
<beans:property name="keys" value="theListKey"/>
</beans:bean>
</listener>
</listeners>
</batch:step>
<batch:step id="runSQLs">
<batch:tasklet transaction-manager="TransactionManager"
ref="runRunSQLs" />
</batch:step>
应从执行代码块填充数据,如下所示:
// ...
ExecutionContext stepContext = this.stepExecution.getExecutionContext();
stepContext.put("theListKey", yourList);
然后在后续步骤中,可以使用带有List
a注释的后计算挂钩检索此@BeforeStep
,如下所示:
@BeforeStep
public void retrieveSharedData(StepExecution stepExecution) {
JobExecution jobExecution = stepExecution.getJobExecution();
ExecutionContext jobContext = jobExecution.getExecutionContext();
this.myList = jobContext.get("theListKey");
}
答案 1 :(得分:3)
java config方式。
步骤1:配置ExecutionContextPromotionListener
@Bean
public ExecutionContextPromotionListener executionContextPromotionListener()
{
ExecutionContextPromotionListener executionContextPromotionListener = new ExecutionContextPromotionListener();
executionContextPromotionListener.setKeys(new String[] {"MY_KEY"});
return executionContextPromotionListener;
}
步骤2:使用ExecutionContextPromotionListener配置步骤
@Bean
public Step myStep() {
return stepBuilderFactory.get("myStep")
.<POJO, POJO> chunk(1000)
.reader(reader()
.processor(Processor())
.writer(Writer()
.listener(promotionListener())
.build();
}
第3步:访问处理器中的数据
@BeforeStep
public void beforeStep(StepExecution stepExecution) {
jobExecutionContext = stepExecution.getJobExecution().getExecutionContext();
jobExecutionContext.getString("MY_KEY")
}
第4步:在处理器中设置数据
@BeforeStep
public void beforeStep(StepExecution stepExecution) {
stepExecution.getJobExecution().getExecutionContext().put("MY_KEY", My_value);
}
答案 2 :(得分:2)
如果您想使用ExecutionContext在步骤之间传递信息,我建议三思。通常,这意味着作业设计不完美。 Spring Batch的主要思想是处理大量数据。 ExecutionContext用于存储有关作业/步骤进度的信息,以减少失败时的不必要工作。从设计上讲,您不能将大数据放入ExectionContext。完成步骤后,您应该以可靠可读的形式获取信息-文件,数据库等。此数据可在后续步骤中用作输入。对于简单的作业,我建议仅使用“作业参数”作为信息源。
在您的情况下,“ runGetSQLs”看起来不太适合作为Step的候选对象,但是如果您愿意,可以在“ runRunSQLs”步骤中将其实现为Spring bean和autowire(这又可以说是Step的很好的候选对象) )。根据您的命名,runGetSQLs看起来像ItemReader,而runRunSQLs看起来像ItemWriter。因此,它们是步骤的一部分,而不是不同的步骤。在这种情况下,您无需将信息转移到其他步骤。