这里对Spring Batch 进行批处理实践。

介绍

本文将会讲述SpringBatch 如何搭建并运行起来的。本教程,将会介绍从磁盘读取文件,并写入MySql 中。

什么是Spring Batch

Spring Batch 是Spring的子项目,基于Spring的批处理的框架,通过其可以构建出批量的批处理框架。

官方地址:github.com/spring-projects/spring-batch

入门案例

新建Spring Boot 项目

Spring Batch之批处理实践_Spring Batch

Spring Batch之批处理实践_Spring Batch _02

选择Spring Batch Spring Batch之批处理实践_Spring Batch _03

Spring Batch之批处理实践_Spring Batch _04

继续等待 Spring Batch之批处理实践_Spring Batch _05

pom 依赖如下

  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

  4. <modelVersion>4.0.0</modelVersion>

  5. <parent>

  6. <groupId>org.springframework.boot</groupId>

  7. <artifactId>spring-boot-starter-parent</artifactId>

  8. <version>2.3.1.RELEASE</version>

  9. <relativePath/> <!-- lookup parent from repository -->

  10. </parent>

  11. <groupId>com.example</groupId>

  12. <artifactId>demo</artifactId>

  13. <version>0.0.1-SNAPSHOT</version>

  14. <name>demo</name>

  15. <description>Demo project for Spring Boot</description>

  16.  

  17. <properties>

  18. <java.version>1.8</java.version>

  19. </properties>

  20.  

  21. <dependencies>

  22. <dependency>

  23. <groupId>org.springframework.boot</groupId>

  24. <artifactId>spring-boot-starter-batch</artifactId>

  25. </dependency>

  26. <dependency>

  27. <groupId>org.springframework.boot</groupId>

  28. <artifactId>spring-boot-starter-web</artifactId>

  29. </dependency>

  30.  

  31. <dependency>

  32. <groupId>org.springframework.boot</groupId>

  33. <artifactId>spring-boot-starter-test</artifactId>

  34. <scope>test</scope>

  35. <exclusions>

  36. <exclusion>

  37. <groupId>org.junit.vintage</groupId>

  38. <artifactId>junit-vintage-engine</artifactId>

  39. </exclusion>

  40. </exclusions>

  41. </dependency>

  42. <dependency>

  43. <groupId>org.springframework.batch</groupId>

  44. <artifactId>spring-batch-test</artifactId>

  45. <scope>test</scope>

  46. </dependency>

  47. </dependencies>

  48.  

  49. <build>

  50. <plugins>

  51. <plugin>

  52. <groupId>org.springframework.boot</groupId>

  53. <artifactId>spring-boot-maven-plugin</artifactId>

  54. </plugin>

  55. </plugins>

  56. </build>

  57.  

  58. </project>

什么是 Spring Batch works

Spring Batch之批处理实践_Spring Batch _06

一个job有读写处理这三个部分组成。通过JobLauncher启动Job 步骤为 读、处理、写 三个步骤

一个例子

初始化目录结构如下 Spring Batch之批处理实践_Spring Batch _07

读取

从数组中读取三个字符

  1. package com.example.demo.step;

  2.  

  3. import org.springframework.batch.item.ItemReader;

  4. import org.springframework.batch.item.NonTransientResourceException;

  5. import org.springframework.batch.item.ParseException;

  6. import org.springframework.batch.item.UnexpectedInputException;

  7.  

  8. public class Reader implements ItemReader<String> {

  9. private String[] message = {"ming", "mingming", "mingmingming"};

  10.  

  11. private int count = 0;

  12.  

  13. @Override

  14. public String read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {

  15. if(count < message.length){

  16. return message[count++];

  17. }else{

  18. count = 0;

  19. }

  20. }

  21. }

每次将会调用reader 方法,进行读取一个,

 

 

处理

字符串转为大写

  1. package com.example.demo.step;

  2.  

  3. import org.springframework.batch.item.ItemProcessor;

  4.  

  5. public class Processor implements ItemProcessor<String, String> {

  6. @Override

  7. public String process(String s) throws Exception {

  8. return s.toUpperCase();

  9. }

  10. }

字符串将会调用其方法将其处理为大写

  1. package com.example.demo.step;

  2.  

  3. import org.springframework.batch.item.ItemWriter;

  4.  

  5. import java.util.List;

  6.  

  7. public class Writer implements ItemWriter<String> {

  8. @Override

  9. public void write(List<? extends String> list) throws Exception {

  10. for (String s : list) {

  11. System.out.println("Writing the data " + s);

  12. }

  13. }

  14. }

监听

任务成功完成后往控制台输出一行字符串

  1. package com.example.demo.step;

  2.  

  3. import org.springframework.batch.core.BatchStatus;

  4. import org.springframework.batch.core.JobExecution;

  5. import org.springframework.batch.core.listener.JobExecutionListenerSupport;

  6.  

  7. public class JobCompletionListener extends JobExecutionListenerSupport {

  8. @Override

  9. public void afterJob(JobExecution jobExecution) {

  10. // 项目完成以后调用

  11. if(jobExecution.getStatus() == BatchStatus.COMPLETED){

  12. System.out.println("项目已经完成");

  13. }

  14. }

  15. }

Config

对项目进行配置

  1. package com.example.demo.config;

  2.  

  3. import com.example.demo.step.JobCompletionListener;

  4. import com.example.demo.step.Processor;

  5. import com.example.demo.step.Reader;

  6. import com.example.demo.step.Writer;

  7. import org.springframework.batch.core.Job;

  8. import org.springframework.batch.core.JobExecutionListener;

  9. import org.springframework.batch.core.Step;

  10. import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;

  11. import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;

  12. import org.springframework.batch.core.launch.support.RunIdIncrementer;

  13. import org.springframework.beans.factory.annotation.Autowired;

  14. import org.springframework.context.annotation.Bean;

  15. import org.springframework.context.annotation.Configuration;

  16.  

  17.  

  18. @Configuration

  19. public class BatchConfig {

  20. @Autowired

  21. public JobBuilderFactory jobBuilderFactory;

  22.  

  23. @Autowired

  24. public StepBuilderFactory stepBuilderFactory;

  25.  

  26. @Bean

  27. public Job processJob() {

  28. return jobBuilderFactory.get("processJob")

  29. .incrementer(new RunIdIncrementer()).listener(listener())// 监听

  30. .flow(orderStep1()).end().build(); // 创建步骤1

  31. }

  32.  

  33. @Bean

  34. // 步骤1 bean 先读再写

  35. public Step orderStep1() {

  36. return stepBuilderFactory.get("orderStep1").<String, String> chunk(1)

  37. .reader(new Reader()).processor(new Processor()) // 读取。处理

  38. .writer(new Writer()).build(); // 最后写

  39. }

  40.  

  41. @Bean

  42. public JobExecutionListener listener() {

  43. return new JobCompletionListener(); // 创建监听

  44. }

  45.  

  46. }

配置Controller

用来启动应用

  1. package com.example.demo.controller;

  2.  

  3. import org.springframework.batch.core.Job;

  4. import org.springframework.batch.core.JobParameters;

  5. import org.springframework.batch.core.JobParametersBuilder;

  6. import org.springframework.batch.core.launch.JobLauncher;

  7. import org.springframework.beans.factory.annotation.Autowired;

  8. import org.springframework.web.bind.annotation.RequestMapping;

  9. import org.springframework.web.bind.annotation.RestController;

  10.  

  11.  

  12. @RestController

  13. public class JobInvokerController {

  14. @Autowired

  15. JobLauncher jobLauncher;

  16.  

  17. @Autowired

  18. Job processJob;

  19.  

  20. @RequestMapping("/invokejob")

  21. public String handle() throws Exception {

  22.  

  23. JobParameters jobParameters = new JobParametersBuilder().addLong("time", System.currentTimeMillis())

  24. .toJobParameters();

  25. jobLauncher.run(processJob, jobParameters);

  26.  

  27. return "Batch job has been invoked";

  28. }

  29.  

  30. }

配置文件
  1. spring:

  2. batch:

  3. job:

  4. enabled: false

  5. datasource:

  6. url: jdbc:h2:file:./DB

  7. jpa:

  8. properties:

  9. hibernate:

  10. hbm2ddl:

  11. auto: update

Spring Batch在加载的时候job默认都会执行,把spring.batch.job.enabled置为false,即把job设置成不可用,应用便会根据jobLauncher.run来执行。下面2行是数据库的配置,不配置也可以,使用的嵌入式数据库h2

添加注解

Spring Boot入口类:加注解@EnableBatchProcessing

  1. package com.example.demo;

  2.  

  3. import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;

  4. import org.springframework.boot.SpringApplication;

  5. import org.springframework.boot.autoconfigure.SpringBootApplication;

  6.  

  7. @SpringBootApplication

  8. @EnableBatchProcessing

  9. public class DemoApplication {

  10.  

  11. public static void main(String[] args) {

  12. SpringApplication.run(DemoApplication.class, args);

  13. }

  14.  

  15. }

Run

此时项目run 访问 http://localhost:8080/invokejob 项目已经启动

Spring Batch之批处理实践_Spring Batch _08

Spring Batch之批处理实践_Spring Batch _09

 

Spring Batch之批处理实践_Spring Batch _10