简介
企业域内的许多应用程序都需要批量处理才能在关键任务环境中执行业务操作。这些业务操作包括自动化,复杂的海量信息处理,无需用户交互即可最有效地进行处理。这些操作通常包括基于时间的事件(例如,月末计算,通知或通信),周期性应用非常大的数据集重复处理的复杂业务规则(例如,保险利益确定或费率调整)或所接收信息的集成从通常需要以事务处理方式进行格式化,验证和处理的内部和外部系统进入记录系统。批处理每天用于为企业处理数十亿笔事务。
Spring Batch 是一个轻量级的,全面的批处理框架,旨在支持开发对企业系统的日常运行至关重要的强大的批处理应用程序。
Spring Batch 不是一个调度框架。商业和开放源代码空间(例如 Quartz,Tivoli,Control-M 等)中都有许多好的企业调度程序。它旨在与调度程序结合使用,而不是替换调度程序。
Spring Batch 实现的特性包括数据验证、格式化输出、轶可重用的方式实现复杂逻辑以及处理大数据的能力。
Spring Batch架构
如下图所示:Spring Batch的分层配置由三层组成。
Application:应用层,包括所有用来构建批处理的定制化代码和配置。业务逻辑、服务以及组织任务的配置等,都是应用层所关心的内容。应用层不不是在其他两层之上,而是封装了其他两层。
Batch Core:核心层,包含用于定义批处理域的所有部分。核心组件的元素包括作业(Job)和步骤(Step)接口,以及用来执行作业的如下两个接口:JobLauncher和JobParameters。
Batch Infrastructure:基础设施层,在处理任何东西前,都需要读取或写入文件、数据等。在任务失败后,必须能够进行重试,这些部分被认为是一些通用的基础设施。
初体验
创建工程:pom依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
主启动类:
@EnableBatchProcessing
@SpringBootApplication
public class BootBatchApplication {
public static void main(String[] args) {
SpringApplication.run(BootBatchApplication.class, args);
}
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public Step step() {
return this.stepBuilderFactory.get("step1")
.tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution,
ChunkContext chunkContext) {
System.out.println("Hello, World!");
return RepeatStatus.FINISHED;
}
}).build();
}
@Bean
public Job job() {
return this.jobBuilderFactory.get("job")
.start(step())
.build();
}
}
运行结果:
分析
@EnableBatchProcessing
进入该注解:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(BatchConfigurationSelector.class)
public @interface EnableBatchProcessing {
boolean modular() default false;
}
该注解import了另一个组件BatchConfigurationSelector
,该类实现了ImportSelector
接口,熟悉Spring的应该知道,通过该接口批量注册组件
public class BatchConfigurationSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
Class<?> annotationType = EnableBatchProcessing.class;
AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(
annotationType.getName(), false));
Assert.notNull(attributes, String.format("@%s is not present on importing class '%s' as expected",
annotationType.getSimpleName(), importingClassMetadata.getClassName()));
String[] imports;
if (attributes.containsKey("modular") && attributes.getBoolean("modular")) {
imports = new String[] { ModularBatchConfiguration.class.getName() };
}
else {
imports = new String[] { SimpleBatchConfiguration.class.getName() };
}
return imports;
}
}
而EnableBatchProcessing
注解的modular方法默认返回false,通过BatchConfigurationSelector,不难看出,该类会向IOC容器中添加一个SimpleBatchConfiguration
配置类。
该配置类又向容器中添加了一下几个组件:
- JobRepository 记录作业运行时的状态
- JobLauncher 启动作业
- JobRegistry 在使用特定的启动器实现时找到作业
- JobExplorer 使用JobRepository 执行只读操作
- PlatformTransactionManager 在工作过程中处理事务
下面两个bean在SimpleBatchConfiguration
的父类AbstractBatchConfiguration
中定义的
- JobBuilderFactory 作业构建工厂
- StepBuilderFactory 步骤构建工厂
因为在EnableBatchProcessing
中向容器添加了JobBuilderFactory 和StepBuilderFactory ,所以我们想要使用,就可以直接@Autowired了。
并且通过他们来创建我们自定义的Job
和Step
那么上述的Job是怎么运行的呢?
在SpringBatch中有一个组件JobLauncherApplicationRunner
,实现了ApplicationRunner
接口,在SpringBoot容器启动时,会调用所有的ApplicationRunner
接口的run方法
execute后续就不往下看了。