SpringBatch 框架
SpringBatch 是一个轻量级的、完善的批处理框架,旨在帮助企业建立健壮、高效的批处理应用。它是一个批处理应用框架,不是调度框架,需要配合调度框架来完成批处理工作。
这里不会介绍 SpringBatch 的基本概念,仅仅记录一些使用技巧和模板。
对单个 job 进行单元测试
1.pom.xml 引入测试框架
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
2.配置文件设置 job 不自动运行
spring.batch.job.enabled=false
3.单元测试类
@SpringBootTest
public class BatchTest {
@Autowired
private JobLauncher simpleJobLauncher;
@Autowired
private Job testJob;
@Autowired
private ExecutionContext executionContext;
@Test
public void test() throws Exception {
// 参数
JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
jobParametersBuilder.addString("tableName", "foo");
jobParametersBuilder.addDate("date", new Date());
// context 上下文
TestJobContext context = TestJobContext.builder().name("chenglong").userId("1").build();
executionContext.put("context", context);
simpleJobLauncher.run(testJob, jobParametersBuilder.toJobParameters());
}
}
基本框架模板
这里介绍一种使用 SpringBatch 的基本套路
@Qualifier("testJob")
@Bean
public Job job() throws Exception {
return jobBuilderFactory.get("job")
.validator(jobParamValidator)
.start(initOperatorStep())
.next(myDecider)
.on("runNext")
.to(workStep())
.end()
.build();
}
@Bean
public Step workStep() throws Exception {
return stepBuilderFactory.get("workStep")
.<Foo, Bar>chunk(10)
.reader(dataSourceItemReader())
.processor(testProcessor)
.writer(dataSourceItemWriter(null))
.build();
}
@Bean
public Step initOperatorStep() {
return stepBuilderFactory.get("initOperatorStep").tasklet((contribution, chunkContext) -> null).build();
}
首先使用 jobParamValidator 对参数进行校验。
initOperatorStep 是运行时准备的代码,比如对任务进行记录,参数的组装等工作,它是一个 tasklet,有非常大的自定义的空间。
myDecider 是决策器,可以决定是否进一步执行下一步操作,比如有些定时任务只有满足特定条件才会真正进行,在这里就可以进行过滤。这里当决策器返回 runNext 字符串的时候就继续执行 workStep 否则结束流程。
workStep 就是一个非常常规的 SpringBatch 批处理的模式,使用 chunk 模式,reader 后进行 processor 最后再进行写操作。
一些小问题
@StepScope 注解
在 Spring 框架中 @Bean 注解的类生命周期是和 Spring 绑定的,一般 IoC 容器都会默认使用 singleton 作为 bean 的作用范围。
这就导致了 job 的底层单位(reader,processor,writer,tasklet)在 job 启动后就参数就没有办法修改,所以有了这个 scope,来标记当前 bean 的生命周期和 step 同步。
完整代码:https://gitee.com/ManaStuDent/project 4play分支 op-batch模块