Spring Batch : 在不同steps间传递数据
参考文档:
How can we share data between the different steps of a Job in Spring Batch?
有三种方式:
- Use
StepContextand promote it toJobContextand you have access to it from each step, you must as noted obey limit in size - Create
@JobScopebean and add data to that bean,@Autowireit 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) - 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
idsinJobContextand access when needed and delete that temporary table when job finishes successfully.
使用 JobContext
通过step_execution 或者 job_execution来在不同step中传递数据。
但是如果数据量大的话,这将不是一种好的方式.因为spring batch默认会通过job repository将 step_execution和job_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间传递数据的更多相关文章
- 小菜学习Winform(五)窗体间传递数据
前言 做项目的时候,winfrom因为没有B/S的缓存机制,窗体间传递数据没有B/S页面传递数据那么方便,今天我们就说下winfrom中窗体传值的几种方式. 共有字段传递 共有字段传递实现起来很方便, ...
- C#中使用SendMessage在进程间传递数据的实例
原文:C#中使用SendMessage在进程间传递数据的实例 1 新建解决方案SendMessageExample 在解决方案下面新建三个项目:CopyDataStruct,Receiver和Send ...
- StoryBoard学习(5):使用segue页面间传递数据
StoryBoard学习(5):使用segue页面间传递数据 函数: - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sen ...
- 使用Bundle在Activity间传递数据
使用Bundle在Activity间传递数据 源Activity public class SourceActivty extends Activity { private Intent intent ...
- WinForm 窗体间传递数据
前言 做项目的时候,winfrom因为没有B/S的缓存机制,窗体间传递数据没有B/S页面传递数据那么方便,今天我们就说下winfrom中窗体传值的几种方式. 共有字段传递 共有字段传递实现起来很方便, ...
- 在微信小程序页面间传递数据总结
在微信小程序页面间传递数据 原文链接:https://www.jianshu.com/p/dae1bac5fc75 在开发微信小程序过程之中,遇到这么一些需要在微信小程序页面之间进行数据的传递的情况, ...
- iPhone应用程序间传递数据
前一篇简单的介绍了iPhone应用程序间通信,主要是通过在被调用应用的Info.plist中加入URL方案,在应用中通过openUrl来实现程序的调用.而应用程序间的数据传递则可以更具url来实现,例 ...
- Android程序中Acticity间传递数据
在Android开发过程中,在不同的Acitivity之间传递数据的情况是非常常见的.我花费了一点时间来总结Acitivity之间的数据传递,记录下来. 1.简单传递键值对 这种传递方式非常简单,只需 ...
- Android学习手记(3) Activity间传递数据
1. 简单数据传递 建立两个Activity,名称分别为MainActivity和TheAty,在MainActivity中新建一个Button,id为btnStartAty.在TheAty中新建一个 ...
随机推荐
- 一、Windows部署RabbitMQ
RabbitMQ官方网站非常详细,以下只是本人学习过程的整理 一.Windows部署RabbitMQ:https://www.cnblogs.com/yangleiyu/p/15539618.html ...
- 12组-Alpha冲刺-2/6
一.基本情况 队名:字节不跳动 组长博客:https://www.cnblogs.com/147258369k/p/15535639.html 小组人数:10人 二.冲刺概况汇报 侯钦凯 过去两天完成 ...
- dart系列之:dart类的扩展
目录 简介 使用extends 抽象类和接口 mixins 总结 简介 虽然dart中的类只能有一个父类,也就是单继承的,但是dart提供了mixin语法来绕过这样限制. 今天,和大家一起来探讨一下d ...
- 手把手教你学Dapr - 8. 绑定
目录 手把手教你学Dapr - 1. .Net开发者的大时代 手把手教你学Dapr - 2. 必须知道的概念 手把手教你学Dapr - 3. 使用Dapr运行第一个.Net程序 手把手教你学Dapr ...
- 基于Netty4手把手实现一个带注册中心和注解的Dubbo框架
阅读这篇文章之前,建议先阅读和这篇文章关联的内容. 1. 详细剖析分布式微服务架构下网络通信的底层实现原理(图解) 2. (年薪60W的技巧)工作了5年,你真的理解Netty以及为什么要用吗?(深度干 ...
- python实现模糊操作
目录: (一)模糊或平滑与滤波的介绍 (二)均值模糊 (1) 原理 (2)代码实现-----均值模糊函数blur() (三)中值模糊------mediaBlur函数 (四)高斯模糊------Gau ...
- <C#任务导引教程>练习六
//54五名学生参加了两门课程的考试,试输入成绩,统计出各科的最高分,最低分,平均分及每个学生的平均成绩(要求用对话框显示成绩统计结果)using System;using System.Window ...
- [bzoj5508]甲苯先生的字符串
首先定义状态f[i][j]表示长度为i的串以j为结尾有多少符合条件的串,发现$f[i][j]=\sum f[i-1][k]$(j和k可以相邻),这个用矩阵乘法优化一下即可. 1 #include< ...
- tomcat更改端口号and设置cmd别名
1.修改端口号 打开tomcat的conf\server.xml 这个是项目访问的端口号了 这个也要注意更改一下,避免冲突 2.接下来要设置cmd别名 用文本编辑器打开bin\catalina.bat ...
- Python迭代器生成器与生成式
Python迭代器生成器与生成式 什么是迭代 迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果.每一次对过程的重复称为一次"迭代",而每一次迭代得到的结果会作为下一次迭 ...