大家好,又见面了,我是你们的朋友全栈君。
写在前面:
我是「沸羊羊_」,昵称来自于姓名的缩写 fyy ,之前呕心沥血经营的博客因手残意外注销,现经营此账号。
本人是个小菜,正向着全栈工程师的方向努力着,文章可能并不高产,也很基础,但每写一篇都在用心总结,请大佬勿喷。
如果您对编程有兴趣,请关注我的动态,一起学习研究。
感谢每位读者!
一、概述
Spring Batch是一个轻量级,全面的批处理框架。
一个典型的批处理过程可能是:
- 从数据库,文件或队列中读取大量记录。
- 以某种方式处理数据。
- 以修改之后的形式写回数据
Spring Batch 应用架构图:
一个Batch(批处理)过程由一个Job(作业)组成。这个实体封装了整个批处理过程。
一个Job(作业)可以由一个或多个Step(步骤)组成。在大多数情况下,一个步骤将读取数据(通过ItemReader),处理数据(使用ItemProcessor),然后写入数据(通过ItemWriter)。
JobLauncher处理启动一个Job(作业)。
最后,JobRepository存储关于配置和执行的Job(作业)的元数据。
二、实例
1、新建 springboot项目
创建项目传送门
选择配置,添加依赖,GENERATE 后导入到你的IDE
2、springboot 项目配置
2.1 在新建项目时添加依赖了,就会发现pom中引入了 spring-barch的相关依赖,如新建项目时没有添加依赖,则需要手动添加。
//pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
2.2 为主程序的@SpringBootApplication注解添加exclude属性,可以防止 SpringBoot 为数据库连接自动配置 DataSource
//主程序
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class Springbatch2020829Application {
public static void main(String[] args) {
SpringApplication.run(Springbatch2020829Application.class, args);
}
}
2.3 新建实体model
//Person.java
public class Person {
private String firstName;
private String lastName;
}
//构造函数,get,set方法, toString()方法略
2.4 配置 Spring Batch Job
2.4.1 新建 BatchConfig 类,重写父类 setDataSource 方法
//BatchConfig.java
@Configuration
@EnableBatchProcessing
public class BatchConfig extends DefaultBatchConfigurer {
@Override
public void setDataSource(DataSource dataSource) {
}
}
2.4.2 新建 HelloWorldJobConfig 类,配置 job ,step
//HelloWorldJobConfig.java
@Configuration
public class HelloWorldJobConfig {
//新建 Job,Spring 将自动注入 jobBuilders ,stepBuilders两个 beans
@Bean
public Job helloWorlJob(JobBuilderFactory jobBuilders,
StepBuilderFactory stepBuilders) {
return jobBuilders.get("helloWorldJob")
.start(helloWorldStep(stepBuilders)).build();
}
//新建 Step,使用 StepBuilderFactory 创建
@Bean
public Step helloWorldStep(StepBuilderFactory stepBuilders) {
return stepBuilders.get("helloWorldStep")
.<Person, String>chunk(10).reader(reader())
.processor((Function<? super Person, ? extends String>) processor()).writer(writer()).build();
}
//读取数据,指定需要读取的资源
@Bean
public FlatFileItemReader<Person> reader() {
return new FlatFileItemReaderBuilder<Person>()
.name("personItemReader")
.resource(new ClassPathResource("csv/persons.csv"))
.delimited().names(new String[] {
"firstName", "lastName"})
.targetType(Person.class).build();
}
//处理数据
@Bean
public PersonItemProcessor processor() {
return new PersonItemProcessor();
}
//写入数据,指定写入路径文件
@Bean
public FlatFileItemWriter<String> writer() {
return new FlatFileItemWriterBuilder<String>()
.name("greetingItemWriter")
.resource(new FileSystemResource(
"target/test-outputs/greetings.txt"))
.lineAggregator(new PassThroughLineAggregator<>()).build();
}
}
2.5 处理数据
//PersonItemProcessor.java
public class PersonItemProcessor
implements ItemProcessor<Person, String> {
private static final Logger LOGGER =
LoggerFactory.getLogger(PersonItemProcessor.class);
//打印日志信息
@Override
public String process(Person person) throws Exception {
String greeting = "Hello " + person.getFirstName() + " "
+ person.getLastName() + "!";
LOGGER.info("converting '{}' into '{}'", person, greeting);
return greeting;
}
}
2.6 测试 Spring Batch 示例
//测试类
package com.fyy.springbatch;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(
classes = {
Springbatch2020829ApplicationTests.BatchTestConfig.class})
public class Springbatch2020829ApplicationTests {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Test
public void testHelloWorldJob() throws Exception {
JobExecution jobExecution = jobLauncherTestUtils.launchJob();
assertThat(jobExecution.getExitStatus().getExitCode())
.isEqualTo("COMPLETED");
}
@Configuration
@Import({
BatchConfig.class, HelloWorldJobConfig.class})
static class BatchTestConfig {
@Autowired
private Job helloWorlJob;
@Bean
JobLauncherTestUtils jobLauncherTestUtils()
throws NoSuchJobException {
JobLauncherTestUtils jobLauncherTestUtils =
new JobLauncherTestUtils();
jobLauncherTestUtils.setJob(helloWorlJob);
return jobLauncherTestUtils;
}
}
}
2.7 启动项目,在 target/test-outputs/greetings.txt 文件中找到结果。
三、理解
JobRepository
从字面上可以理解为”任务仓库”,如果把一个批处理比作一个任务的话,这个仓库存储了很多这种任务。JobRepository 会将任务包括其状态等数据持久化,存储到许多数据库中。Spring Batch 默认会提供一个 SimpleJobRepository 仓库,方便我们开启批处理。
Job
“任务”。每个批处理都是一个任务,除了任务本身之外,任务也存在成功和失败等等状态,所以可以引出两个概念 JobInstance 与 JobExecution 。job 是一个接口,JobInstance 是其实现,代表了“任务”本身,提供了 getJobName、getInstanceId 等方法供我们获取任务本身的一些属性。JobExecution 代表任务的状态,如创建时间、结束时间、结束状态、抛出的异常等等。
Step
“步骤”。批处理任务肯定有非常多的步骤,如一个最基本的数据库同步,从 A 数据库读取数据,存入到 B 数据库中,这里就分为了两个步骤。在 Spring Batch 中,一个任务可以有很多个步骤,每个步骤大致分为三步:读、处理、写,其对应的类分别就是 Item Reader,Item Processor,Item Writer。
JobLauncher
“任务装置”。如火箭发射装置就是用来操作火箭发射的,这里的任务装置就是用来执行任务的。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/140381.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...