文章目录

  • 一、自定义CustomItemReader
  • 二、job 监听器
  • 三、配置job
  • 四、改造CustomItemReader,发生异常批处理作业从停止的地方重新启动

前言:在一些业务场景中,可能现有的reader不符合我们的要求,SpringBatch提供自定义reader,实现ItemReader接口,满足我们业务场景。

SpringBatch其它文章直通车:

  • SpringBatch读单个文件(FlatFileItemReader)和写单个文件(FlatFileItemWriter)(一)
  • SpringBatch顺序读取多文件(MultiResourceItemReader)和顺序写文件(MultiResourceItemWriter)(二)
  • SpringBatch读数据库(MyBatisPagingItemReader)(三)
  • SpringBatch读文件(FlatFileItemReader)写据库(MyBatisBatchItemWriter)(四)
  • SpringBatch 监听器之Job监听器(JobExecutionListener)和Step监听器(StepExecutionListener)(五)
  • SpringBatch 监听器之Chunk监听器(ChunkListener)和Skip监听器(SkipListener)(六)
  • SpringBatch 多线程(TaskExecutor)启动Job详解 (七)
  • SpringBatch 配置并行启动Job详解 (八)
  • SpringBatch 批处理分区(Partitioner )分片(九)
  • SpringBatch tasklet实现和用法(十)
  • SpringBatch 读取JSON(JsonItemReader)用法(十一)
  • SpringBatch 写文件JSON(JsonFileItemWriter)用法(十二)
  • SpringBatch 读取xml文件(StaxEventItemReader)用法(十三)
  • SpringBatch 写xml文件(StaxEventItemWriter)用法(十四)

代码已上传GitHub上面地址:git源码地址

一、自定义CustomItemReader

创建了一个简单的ItemReader实现,它从提供的列表中读取数据。我们首先实现ItemReader最基本的read方法

package com.sl.common;import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;import java.util.List;/*** 自定义reader* @author shuliangzhao* @Title: CustomItemReader* @ProjectName spring-boot-learn* @Description: TODO* @date 2019/9/21 14:49*/
public class CustomItemReader<T> implements ItemReader<T> {private List<String> list;public CustomItemReader(List<String> list) {this.list = list;}@Overridepublic T read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {if (list.size() > 0 && !list.isEmpty()) {return (T)list.remove(0);}return null;}
}

二、job 监听器

job执行之前加载数据供reader使用

package com.sl.listener;import com.sl.common.CommonConstants;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.stereotype.Component;/*** @author shuliangzhao* @Title: CustomJobListener* @ProjectName spring-boot-learn* @Description: TODO* @date 2019/9/21 14:59*/
@Component
public class CustomJobListener implements JobExecutionListener {@Overridepublic void beforeJob(JobExecution jobExecution) {CommonConstants.getList().add("hello");CommonConstants.getList().add("springbatch");}@Overridepublic void afterJob(JobExecution jobExecution) {}
}

三、配置job

package com.sl.config;import com.sl.common.CommonConstants;
import com.sl.common.CustomItemReader;
import com.sl.listener.CustomJobListener;
import com.sl.writer.CustomItemWriter;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 自定义重启reader* @author shuliangzhao* @Title: CustomConfiguration* @ProjectName spring-boot-learn* @Description: TODO* @date 2019/9/21 14:55*/
@Configuration
@EnableBatchProcessing
public class CustomConfiguration {@Autowiredprivate JobBuilderFactory jobBuilderFactory;@Autowiredprivate StepBuilderFactory stepBuilderFactory;@Autowiredprivate CustomJobListener customJobListener;@Autowiredprivate CustomItemWriter customItemWriter;@Beanpublic Job customJob() {return jobBuilderFactory.get("customJob").listener(customJobListener).start(customStep()).build();}@Beanpublic Step customStep() {return stepBuilderFactory.get("customStep").chunk(10).reader(customItemReader()).writer(customItemWriter).build();}@Bean@StepScopepublic CustomItemReader customItemReader() {return new CustomItemReader(CommonConstants.getList());}
}

敲黑板:如果这个job在执行过程中发生错误,是不能重启。接下来我们讲解怎么改进reader可以让我们的job在发生异常,批处理作业从停止的地方重新启动。

四、改造CustomItemReader,发生异常批处理作业从停止的地方重新启动

目前,如果处理被中断并重新开始,ItemReader必须从头开始。在许多场景中,这实际上是有效的,但有时更可取的做法是,批处理作业从停止的地方重新启动。关键的区别通常是阅读器是有状态的还是无状态的。无状态读取器不需要担心可重启性,但是有状态读取器必须尝试在重启时重新构建其最后一个已知状态。出于这个原因,我们建议尽可能保持自定义读取器处于无状态,因此不必担心可重启性。

CustomItemReader还需要实现接口ItemStream

package com.sl.common;import org.springframework.batch.item.*;import java.util.List;/*** 自定义reader* @author shuliangzhao* @Title: CustomItemReader* @ProjectName spring-boot-learn* @Description: TODO* @date 2019/9/21 14:49*/
public class CustomRestaItemReader<T> implements ItemReader<T> , ItemStream {private List<T> list;int currentIndex = 0;private static final String CURRENT_INDEX = "current.index";public CustomRestaItemReader(List<T> list) {this.list = list;}@Overridepublic T read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {if (currentIndex < list.size()) {return list.get(currentIndex++);}return null;}@Overridepublic void open(ExecutionContext executionContext) throws ItemStreamException {if(executionContext.containsKey(CURRENT_INDEX)){currentIndex = new Long(executionContext.getLong(CURRENT_INDEX)).intValue();}else{currentIndex = 0;}}@Overridepublic void update(ExecutionContext executionContext) throws ItemStreamException {executionContext.putLong(CURRENT_INDEX, new Long(currentIndex).longValue());}@Overridepublic void close() throws ItemStreamException {}
}

实现reader重启关键方法是open方法和update方法

SpringBatch 自定义ItemReader和可重新启动Reader(十五)相关推荐

  1. FreeSql (三十五)CodeFirst 自定义特性

    比如项目内已经使用了其它 orm,如 efcore,这样意味着实体中可能存在 [Key],但它与 FreeSql [Column(IsPrimary = true] 不同. Q: FreeSql 实体 ...

  2. 十五、Typora官方主题 + 自定义主题

    十五.Typora官方主题 + 自定义主题 1.下载官方主题 2.在官方主题的基础上自定义 1.下载官方主题 首先去Typora官网下载自己喜欢的主题:官方主题下载 例如我这里选择 Vue 我们只用到 ...

  3. [系统安全] 四十五.APT系列(10)Metasploit后渗透技术信息收集、权限提权和功能模块详解

    您可能之前看到过我写的类似文章,为什么还要重复撰写呢?只是想更好地帮助初学者了解病毒逆向分析和系统安全,更加成体系且不破坏之前的系列.因此,我重新开设了这个专栏,准备系统整理和深入学习系统安全.逆向分 ...

  4. 十五步骤手把手学会制作网吧XP母盘制作

    中国网吧在线 ->  网吧大学 -  技术学院 - 网管技术 - 正文 十五步骤手把手学会制作网吧XP母盘制作 2008-4-9 12:35:05 来源: 中国网吧在线 编辑:陈峰 [网友评论] ...

  5. WCF技术剖析之十五:数据契约代理(DataContractSurrogate)在序列化中的作用

    如果一个类型,不一定是数据契约,和给定的数据契约具有很大的差异,而我们要将该类型的对象序列化成基于数据契约对应的XML.反之,对于一段给定的基于数据契约的XML,要通过反序列化生成该类型的对象,我们该 ...

  6. 第十五章 IO流(转换流 字符流 字符缓冲流 打印流)

    Java基础15 第十五章 IO流(转换流 字符流 字符缓冲流 打印流) 15.1 字符编码和字符集 15.1.1 字符编码 15.1.2 字符集 15.1.3 String类getBytes()方法 ...

  7. 第十五章 使用管理门户SQL接口(一)

    文章目录 第十五章 使用管理门户SQL接口(一) 管理门户SQL工具 选择命名空间 用户自定义 执行SQL查询 编写SQL语句 表拖放 执行查询选项 显示计划按钮 SQL语句的结果 查询数据显示 查询 ...

  8. 第二十五章 使用系统监视器 - 应用程序监视器

    文章目录 第二十五章 使用系统监视器 - 配置健康监视器类 设置运行状况监视器选项 应用程序监视器 应用程序监视器概述 第二十五章 使用系统监视器 - 配置健康监视器类 此子菜单中的选项可让自定义 H ...

  9. Linux的基本学习(十五)——认识系统服务

    Linux的基本学习(十五)--认识系统服务 前言 继续学习Linux 什么是daemon与服务(service) 从CentOS 7.x开始,传统的init已经被抛弃,取而代之的是systemd 什 ...

最新文章

  1. a*算法matlab代码_导向滤波算法及其matlab代码实现
  2. Nexus3 使用root无法启动解决
  3. Ghost 的高可用安装 准备篇
  4. Python----Requests库基本使用
  5. boost::hana::is_a用法的测试程序
  6. 用MySql的查询分析语法explain来优化查询和索引
  7. SQL 分页存储过程(转)
  8. go generate介绍及使用
  9. SpringBoot+Vue表单文件上传
  10. 当最后一位不能为空格_清除工作表中的空格/非打印字符?TRIM与CALEN都无法清除时怎么办...
  11. igllib 203 Curvature directions
  12. Output path is shared between the same module error
  13. Unity3D开发工具介绍
  14. c语言头文件及形式,C语言头文件作用及写法
  15. 带省份的下拉框的html语言,js实现省份下拉菜单效果
  16. 华为员工离职心声:菊厂15年退休,感恩公司,让我实现了财务自由!
  17. 计算机word格式,2017年职称计算机Word教程:Word段落格式
  18. windows如何查看内存条型号信息cpu型号信息 # 包括 内存条个数 和 cpu个数
  19. iPhont X适配
  20. 【自己开发小程序】自己怎么开发一个小程序呢?

热门文章

  1. 英语语法---副词详解
  2. TensorFlow 笔记6--迁移学习
  3. 第四范式入选Forrester中国机器学习Now Tech™,成唯一AutoML专注类大型厂商
  4. erlang精要(2)-数制
  5. AI理论知识整理(2)-对称矩阵-特征值与特征向量
  6. 自制操作系统学习笔记(1)-虚拟机启动软盘
  7. 【时间序列】时序预测竞赛之异常检测算法综述
  8. 【NLP】一文搞懂NLP中的对抗训练
  9. 【Python】全网最新最全Pyecharts可视化教程(二):绘制好看的交互式地图教程
  10. 盘一盘推荐系统里值得一读的那些论文