参考文档:

How can we share data between the different steps of a Job in Spring Batch?

Job Scoped Beans in Spring Batch

https://github.com/spring-projects/spring-batch/issues/1335

有三种方式:

  1. Use StepContext and promote it to JobContext and you have access to it from each step, you must as noted obey limit in size
  2. Create @JobScope bean and add data to that bean, @Autowire it where needed and use it (drawback is that it is in-memory structure and if job fails data is lost, migh cause problems with restartability)
  3. We had larger datasets needed to be processed across steps (read each line in csv and write to DB, read from DB, aggregate and send to API) so we decided to model data in new table in same DB as spring batch meta tables, keep ids in JobContext and access when needed and delete that temporary table when job finishes successfully.

使用 JobContext

通过step_execution 或者 job_execution来在不同step中传递数据。

但是如果数据量大的话,这将不是一种好的方式.因为spring batch默认会通过job repository将 step_executionjob_execution进行持久化.

Use ExecutionContextPromotionListener:

首先在第一个Step中放到StepExecution

public class YourItemWriter implements ItemWriter<Object> {
private StepExecution stepExecution;
public void write(List<? extends Object> items) throws Exception {
// Some Business Logic // put your data into stepexecution context
ExecutionContext stepContext = this.stepExecution.getExecutionContext();
stepContext.put("someKey", someObject);
}
@BeforeStep
public void saveStepExecution(Final StepExecution stepExecution) {
this.stepExecution = stepExecution;
}
}

然后使用promotionListener在监听器中将其升级到JobExecution中:

@Bean
public Step step1() {
return stepBuilder
.get("step1")<Company,Company> chunk(10)
.reader(reader()).processor(processor()).writer(writer())
.listener(promotionListener()).build();
} @Bean
public ExecutionContextPromotionListener promotionListener() {
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
listener.setKeys(new String[] {"someKey"});
listener.setStrict(true);
return listener;
}

在第二个Step中使用ExecutionContext获取:

public class RetrievingItemWriter implements ItemWriter<Object> {
private Object someObject;
public void write(List<? extends Object> items) throws Exception {
// ...
}
@BeforeStep
public void retrieveInterstepData(StepExecution stepExecution) {
JobExecution jobExecution = stepExecution.getJobExecution();
ExecutionContext jobContext = jobExecution.getExecutionContext();
this.someObject = jobContext.get("someKey");
}
}

如果你使用的是tasklets的话,可以这样获取:

List<YourObject> yourObjects = (List<YourObject>) chunkContent.getStepContext().getJobExecutionContext().get("someKey");

用自己定义的bean传递数据

创建一个data holder

@Component
@JobScope
public class PublicCompanyHolder { private List<PublicCompanyInfo> publicCompanyList; public List<PublicCompanyInfo> getPublicCompanyList() {
return publicCompanyList;
} public void setPublicCompanyList(List<PublicCompanyInfo> publicCompanyList) {
this.publicCompanyList = publicCompanyList;
} }

在step 1中设置数据:

@Component("pubTasklet")
public class PubTasklet implements Tasklet { @Autowired
private PublicCompanyHolder publicCompanyHolder; public RepeatStatus execute(StepContribution contribution,
ChunkContext chunkContext) throws Exception { List<PublicCompanyInfo> infoContainer = new ArrayList<PublicCompanyInfo>(); for (int i=0; i < 10; i++) {
PublicCompanyInfo info = new PublicCompanyInfo();
info.setPublicCompanyId("ID-" + i);
info.setPublicCompanyName("Name*" + i);
infoContainer.add(info);
}
publicCompanyHolder.setPublicCompanyList(infoContainer); return RepeatStatus.FINISHED;
} }

在step2中取数据:

@Component("pubTasklet2")
public class PubTasklet2 implements Tasklet {
@Autowired
private PublicCompanyHolder publicCompanyHolder; public RepeatStatus execute(StepContribution contribution,
ChunkContext chunkContext) throws Exception {
System.out.println("received holder:" + publicCompanyHolder.getPublicCompanyList()); return RepeatStatus.FINISHED;
} }

job配置

  • define.xml
  <job id="pubJob" restartable="true">
<step id="step1" next="step2">
<tasklet ref="pubTasklet" />
</step>
<step id="step2" next="step1"> // if you do not want to loop, remove next
<tasklet ref="pubTasklet2" />
</step>
<listeners>
<listener ref="pubListener" />
</listeners>
</job>
  • Job Config
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")
.tasklet(new PubTasklet())
.build();
} public Step step2() {
return stepBuilderFactory.get("step2Name")
.tasklet(new PubTasklet2())
.build();
}

Spring Batch : 在不同steps间传递数据的更多相关文章

  1. 小菜学习Winform(五)窗体间传递数据

    前言 做项目的时候,winfrom因为没有B/S的缓存机制,窗体间传递数据没有B/S页面传递数据那么方便,今天我们就说下winfrom中窗体传值的几种方式. 共有字段传递 共有字段传递实现起来很方便, ...

  2. C#中使用SendMessage在进程间传递数据的实例

    原文:C#中使用SendMessage在进程间传递数据的实例 1 新建解决方案SendMessageExample 在解决方案下面新建三个项目:CopyDataStruct,Receiver和Send ...

  3. StoryBoard学习(5):使用segue页面间传递数据

    StoryBoard学习(5):使用segue页面间传递数据 函数: - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sen ...

  4. 使用Bundle在Activity间传递数据

    使用Bundle在Activity间传递数据 源Activity public class SourceActivty extends Activity { private Intent intent ...

  5. WinForm 窗体间传递数据

    前言 做项目的时候,winfrom因为没有B/S的缓存机制,窗体间传递数据没有B/S页面传递数据那么方便,今天我们就说下winfrom中窗体传值的几种方式. 共有字段传递 共有字段传递实现起来很方便, ...

  6. 在微信小程序页面间传递数据总结

    在微信小程序页面间传递数据 原文链接:https://www.jianshu.com/p/dae1bac5fc75 在开发微信小程序过程之中,遇到这么一些需要在微信小程序页面之间进行数据的传递的情况, ...

  7. iPhone应用程序间传递数据

    前一篇简单的介绍了iPhone应用程序间通信,主要是通过在被调用应用的Info.plist中加入URL方案,在应用中通过openUrl来实现程序的调用.而应用程序间的数据传递则可以更具url来实现,例 ...

  8. Android程序中Acticity间传递数据

    在Android开发过程中,在不同的Acitivity之间传递数据的情况是非常常见的.我花费了一点时间来总结Acitivity之间的数据传递,记录下来. 1.简单传递键值对 这种传递方式非常简单,只需 ...

  9. Android学习手记(3) Activity间传递数据

    1. 简单数据传递 建立两个Activity,名称分别为MainActivity和TheAty,在MainActivity中新建一个Button,id为btnStartAty.在TheAty中新建一个 ...

随机推荐

  1. svn与git区别

    代码扫描工具介绍:https://baijiahao.baidu.com/s?id=1629218655164599200&wfr=spider&for=pc Git和SVN的区别与联 ...

  2. ELK集群之elasticsearch(3)

    Elasticsearch-基础介绍及索引原理分析 介绍 Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引 ...

  3. liteIDE配置环境变量

    1.下载安装go https://www.cnblogs.com/Jack-cx/p/9878213.html 2.下载ide https://www.golangtc.com/download/li ...

  4. C#生成新浪微博短网址 示例源码

    using System; using System.Collections.Generic; using System.Linq; using System.Text;     using DotN ...

  5. vue.js3 学习笔记 (一)——mixin 混入

    vue 2 中采用选项式API.如:data.methods.watch.computed以及生命周期钩子函数等等. mixin 混入,提供了一种非常灵活的方式,来分发 vue 组件中的可复用功能,一 ...

  6. 菜鸡的Java笔记

    1.注释 在JAVA中对于注释有三种: 单行注释:// 多行注释:/*--*/ 文档注释:/**--*/ 2.关键字和标识符 在程序中描述类名称,方法名称,变量等概念就需要使用标识符来定义.而在JAV ...

  7. <C#任务导引教程>练习九

    //75,异常情况using System;class Program{    public static void Main()    {        Console.Write("请输 ...

  8. [hdu7034]Array

    令$f(a)_{i}=\min_{i<j\le n,a_{i}=a_{j}}j$​​(特别的,若不存在$j$​​则令$f(a)_{i}=n+1$​​),则有以下性质: 1.对于$b_{i}$​​ ...

  9. [loj3524]钥匙

    由于到达关系具有传递性,可以考虑不断将若干个可以相互到达的点缩点,并且当两个点只能单向到达时,能到达另一个点的点一定不是最小值 由此,我们来考虑dfs,即不断从一个节点开始,遍历其可以到达的点,当发现 ...

  10. [luogu5294]序列

    也是一道保序回归的题,但思路不同于论文中模板题 考虑两个开口向上的二次函数$f(x)$和$g(x)$,求任意实数$x,y$满足$x\le y$且最小化$f(x)+g(y)$,这个最小值可以分类讨论求出 ...