我需要一个tasklet,将目录中的所有文件存储在arraylist中。列表的大小存储在作业执行上下文中。稍后,在另一个步骤中从另一个tasklet访问此计数。怎么做到这一点。我试图存储在jobexecution上下文中,在运行时抛出不可修改的集合异常,
public RepeatStatus execute(StepContribution arg0, ChunkContext arg1)
throws Exception {
StepContext stepContext = arg1.getStepContext();
StepExecution stepExecution = stepContext.getStepExecution();
JobExecution jobExecution = stepExecution.getJobExecution();
ExecutionContext jobContext = jobExecution.getExecutionContext();
jobContext.put("FILE_COUNT",150000);
还将stepexection引用存储在beforestep注释中.still not possioble.kindly让我知道,如何在两个tasklet之间共享数据。
答案 0 :(得分:53)
你至少有4种可能性:
从Tasklet访问JobExecution的代码示例:
设置值
public class ChangingJobExecutionContextTasklet implements Tasklet {
/** {@inheritDoc} */
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
// set variable in JobExecutionContext
chunkContext
.getStepContext()
.getStepExecution()
.getJobExecution()
.getExecutionContext()
.put("value", "foo");
// exit the step
return RepeatStatus.FINISHED;
}
}
提取值
public class ReadingJobExecutionContextTasklet implements Tasklet {
private static final Logger LOG = LoggerFactory.getLogger(ChangingJobExecutionContextTasklet.class);
/** {@inheritDoc} */
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
// pull variable from JobExecutionContext
String value = (String) chunkContext
.getStepContext()
.getStepExecution()
.getJobExecution()
.getExecutionContext()
.get("value");
LOG.debug("Found value in JobExecutionContext:" + value);
// exit the step
return RepeatStatus.FINISHED;
}
}
我为my spring-batch-examples github repository中的前3个解决方案创建了代码示例,请参阅模块 complex 和package interstepcommunication
答案 1 :(得分:5)
另一种方法是使用在步骤执行后调用的StepExecutionListener
。
您的tasklet可以实现它并共享本地属性。
public class ReadingJobExecutionContextTasklet implements Tasklet, StepExecutionListener {
private String value;
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
ExecutionContext jobExecutionContext = stepExecution.getJobExecution().getExecutionContext();
jobExecutionContext.put("key", value);
//Return null to leave the old value unchanged.
return null;
}
}
因此,在这一步中,您的bean是一个tasklet和一个像bellow一样的监听器。 您还应该将步骤的范围配置为"步骤" :
<batch:step id="myStep" next="importFileStep">
<batch:tasklet>
<ref bean="myTasklet"/>
<batch:listeners>
<batch:listener ref="myTasklet"/>
</batch:listeners>
</batch:tasklet>
</batch:step>
<bean id="myTasklet" class="ReadingJobExecutionContextTasklet" scope="step">