深入研究Spring Batch,我想知道如何在作业的不同步骤之间共享数据?
我们可以使用JobRepository吗?如果是的话,我们怎么做?
有没有其他方法可以做到/达到同样的目的?
Win*_*ked 36
作业存储库间接用于在步骤之间传递数据(Jean-Philippe是正确的,最好的方法是将数据放入StepExecutionContext,然后使用详细命名ExecutionContextPromotionListener来将步骤执行上下文键提升为JobExecutionContext.
值得注意的是,有一个监听器可以将JobParameter密钥提升为a StepExecutionContext(更详细的命名JobParameterExecutionContextCopyListener); 如果你的工作步骤不完全相互独立,你会发现你经常使用这些.
否则,您将使用更复杂的方案(如JMS队列或(天堂禁止)硬编码文件位置)在步骤之间传递数据.
至于在上下文中传递的数据的大小,我还建议你保持小的(但我没有任何具体细节)
Jea*_*end 30
从一个步骤,您可以将数据放入StepExecutionContext.然后,向监听器,你可以从促进数据StepExecutionContext到JobExecutionContext.
这JobExecutionContext可以在以下所有步骤中使用.
笨拙:数据必须简短.这些上下文JobRepository通过序列化保存,长度有限(如果我记得很清楚,则为2500个字符).
因此,这些上下文很适合共享字符串或简单值,但不适用于共享集合或大量数据.
共享大量数据并不是Spring Batch的理念.Spring Batch是一组不同的操作,而不是一个巨大的业务处理单元.
Nen*_*zic 17
我会说你有3个选择:
StepContext和推广它JobContext并且您可以从每个步骤访问它,您必须遵守规定服从限制@JobScopebean并向该bean添加数据,@Autowire在需要的地方使用它(缺点是它是内存中的结构,如果作业失败,数据丢失,则会导致重启性问题)ids在JobContext需要时进行访问并在作业成功完成时删除该临时表.小智 7
您可以使用Java Bean对象
通过这种方式,您可以根据需要存储大量数据
这是我保存一个可以通过整个步骤访问的对象的操作。
@Component("myJobListener")
public class MyJobListener implements JobExecutionListener {
    public void beforeJob(JobExecution jobExecution) {
        String myValue = someService.getValue();
        jobExecution.getExecutionContext().putString("MY_VALUE", myValue);
    }
}
<listeners>
         <listener ref="myJobListener"/>
</listeners>
@BeforeStep
public void initializeValues(StepExecution stepExecution) {
String value = stepExecution.getJobExecution().getExecutionContext().getString("MY_VALUE");
}
另一种非常简单的方法,留在这里以供将来参考:
class MyTasklet implements Tasklet {
    @Override
    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) {
        getExecutionContext().put("foo", "bar");
    }
}
和
class MyOtherTasklet implements Tasklet {
    @Override
    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) {
        getExecutionContext().get("foo");
    }   
}
getExecutionContext这是:
ExecutionContext getExecutionContext(ChunkContext chunkContext) {
    return chunkContext.getStepContext()
                       .getStepExecution()
                       .getJobExecution()
                       .getExecutionContext();
}     
将其作为方法放入超类、接口中default,或者直接粘贴到您的Tasklets.
您可以将数据存储在简单对象中。喜欢:
AnyObject yourObject = new AnyObject();
public Job build(Step step1, Step step2) {
    return jobBuilderFactory.get("jobName")
            .incrementer(new RunIdIncrementer())
            .start(step1)
            .next(step2)
            .build();
}
public Step step1() {
    return stepBuilderFactory.get("step1Name")
            .<Some, Any> chunk(someInteger1)
            .reader(itemReader1())
            .processor(itemProcessor1())
            .writer(itemWriter1(yourObject))
            .build();
}
public Step step2() {
    return stepBuilderFactory.get("step2Name")
            .<Some, Any> chunk(someInteger2)
            .reader(itemReader2())
            .processor(itemProcessor2(yourObject))
            .writer(itemWriter2())
            .build();
}
只需在编写器或任何其他方法中向对象添加数据,并在下一步的任何阶段获取它
| 归档时间: | 
 | 
| 查看次数: | 76621 次 | 
| 最近记录: |