当前位置:   article > 正文

Spring Batch快速入门_springbatch教程

springbatch教程

一、Spring Batch简介

在企业开发中可能会面临到一些需要处理较大数据量的场景,例如将一个表的全部数据导入到另一张表结构类似的表中、批量读取一个或多个文件内容并写入到数据库中,又或者将一张表的数据批量更新到另一张表中。Spring Batch可以快速的开发这种场景下的批处理应用程序。
Spring Batch提供了在处理大量数据时必不可少的可重用功能,包括 日志记录/跟踪、事务管理、作业处理统计信息、作业重新启动、跳过和资源管理。对于 大数据量和高性能的批处理任务,Spring Batch 同样提供了高级功能和特性来支持,例如 分区功能、远程功能等,大大简化了批处理应用的开发,将开发人员从复杂的任务配置管理过程中解放出来,让我们可以更多地去关注核心的业务的处理过程。总之,通过 Spring Batch 我们就能够实现简单的或者复杂的和大数据量的批处理作业。

1.1 Spring Batch结构图

  • JobRepository:用来注册job的容器

  • JobLauncher:用来启动Job的接口

  • Job:实际执行的任务,包含一个或多个Step

  • Step:包含ItemReader、ItemProcessor和ItemWriter

  • ItemReader:用来读取数据的接口

  • ItemProcessor:用来处理数据的接口

  • ItemWriter: 用来输出数据的接口

官网地址如下:

1.2 处理架构

任务的处理是在 Step 这个阶段定义的。在 Step 中,需要定义数据的读取、数据的处理、数据的写出操作,在这三个阶段中,数据的处理是真正进行数据处理的地方。具体 Step 的流程如下图所示:

  • Reader(架构图中的 Item Reader):主要的任务是定义数据的读取操作,包括读取文件的位置、对读取首先要进行的划分(如以 ',' 作为分隔符)、将读取到的文件映射到相关对象的属性字段等

  • Process(架构图中的 Item Processor):这里是真正对数据进行处理的地方,数据的处理逻辑都在这里定义

  • Writer(架构图中的 Item Writer):这个阶段的主要任务是定义数据的输出操作,包括将数据写入到数据库等


1.2 Spring Batch数据库表格

当批处理作业需要操作数据库时,Spring Batch要求在数据库中创建好批处理作业的元数据的存储表格。如下,其中以batch开头的表,是Spring Batch用来存储每次执行作业所产生的元数据。而student表则是作为我们这个Demo中数据的来源:

下图显示了所有6张表的ERD模型及其相互关系(摘自官网):

1.3 Spring Batch Sql脚本

在数据库中执行官方元数据模式SQL脚本:

  1. -- do not edit this file
  2. -- BATCH JOB 实例表 包含与aJobInstance相关的所有信息
  3. -- JOB ID由batch_job_seq分配
  4. -- JOB 名称,与spring配置一致
  5. -- JOB KEY 对job参数的MD5编码,正因为有这个字段的存在,同一个job如果第一次运行成功,第二次再运行会抛出JobInstanceAlreadyCompleteException异常。
  6. CREATE TABLE BATCH_JOB_INSTANCE (
  7. JOB_INSTANCE_ID BIGINT NOT NULL PRIMARY KEY ,
  8. VERSION BIGINT ,
  9. JOB_NAME VARCHAR(100) NOT NULL,
  10. JOB_KEY VARCHAR(32) NOT NULL,
  11. constraint JOB_INST_UN unique (JOB_NAME, JOB_KEY)
  12. ) ENGINE=InnoDB;
  13. -- 该BATCH_JOB_EXECUTION表包含与该JobExecution对象相关的所有信息
  14. CREATE TABLE BATCH_JOB_EXECUTION (
  15. JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY ,
  16. VERSION BIGINT ,
  17. JOB_INSTANCE_ID BIGINT NOT NULL,
  18. CREATE_TIME DATETIME NOT NULL,
  19. START_TIME DATETIME DEFAULT NULL ,
  20. END_TIME DATETIME DEFAULT NULL ,
  21. STATUS VARCHAR(10) ,
  22. EXIT_CODE VARCHAR(2500) ,
  23. EXIT_MESSAGE VARCHAR(2500) ,
  24. LAST_UPDATED DATETIME,
  25. JOB_CONFIGURATION_LOCATION VARCHAR(2500) NULL,
  26. constraint JOB_INST_EXEC_FK foreign key (JOB_INSTANCE_ID)
  27. references BATCH_JOB_INSTANCE(JOB_INSTANCE_ID)
  28. ) ENGINE=InnoDB;
  29. -- 该表包含与该JobParameters对象相关的所有信息
  30. CREATE TABLE BATCH_JOB_EXECUTION_PARAMS (
  31. JOB_EXECUTION_ID BIGINT NOT NULL ,
  32. TYPE_CD VARCHAR(6) NOT NULL ,
  33. KEY_NAME VARCHAR(100) NOT NULL ,
  34. STRING_VAL VARCHAR(250) ,
  35. DATE_VAL DATETIME DEFAULT NULL ,
  36. LONG_VAL BIGINT ,
  37. DOUBLE_VAL DOUBLE PRECISION ,
  38. IDENTIFYING CHAR(1) NOT NULL ,
  39. constraint JOB_EXEC_PARAMS_FK foreign key (JOB_EXECUTION_ID)
  40. references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
  41. ) ENGINE=InnoDB;
  42. -- 该表包含与该StepExecution 对象相关的所有信息
  43. CREATE TABLE BATCH_STEP_EXECUTION (
  44. STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY ,
  45. VERSION BIGINT NOT NULL,
  46. STEP_NAME VARCHAR(100) NOT NULL,
  47. JOB_EXECUTION_ID BIGINT NOT NULL,
  48. START_TIME DATETIME NOT NULL ,
  49. END_TIME DATETIME DEFAULT NULL ,
  50. STATUS VARCHAR(10) ,
  51. COMMIT_COUNT BIGINT ,
  52. READ_COUNT BIGINT ,
  53. FILTER_COUNT BIGINT ,
  54. WRITE_COUNT BIGINT ,
  55. READ_SKIP_COUNT BIGINT ,
  56. WRITE_SKIP_COUNT BIGINT ,
  57. PROCESS_SKIP_COUNT BIGINT ,
  58. ROLLBACK_COUNT BIGINT ,
  59. EXIT_CODE VARCHAR(2500) ,
  60. EXIT_MESSAGE VARCHAR(2500) ,
  61. LAST_UPDATED DATETIME,
  62. constraint JOB_EXEC_STEP_FK foreign key (JOB_EXECUTION_ID)
  63. references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
  64. ) ENGINE=InnoDB;
  65. -- 该BATCH_STEP_EXECUTION_CONTEXT表包含ExecutionContext与Step相关的所有信息
  66. CREATE TABLE BATCH_STEP_EXECUTION_CONTEXT (
  67. STEP_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY,
  68. SHORT_CONTEXT VARCHAR(2500) NOT NULL,
  69. SERIALIZED_CONTEXT TEXT ,
  70. constraint STEP_EXEC_CTX_FK foreign key (STEP_EXECUTION_ID)
  71. references BATCH_STEP_EXECUTION(STEP_EXECUTION_ID)
  72. ) ENGINE=InnoDB;
  73. -- 该表包含ExecutionContext与Job相关的所有信息
  74. CREATE TABLE BATCH_JOB_EXECUTION_CONTEXT (
  75. JOB_EXECUTION_ID BIGINT NOT NULL PRIMARY KEY,
  76. SHORT_CONTEXT VARCHAR(2500) NOT NULL,
  77. SERIALIZED_CONTEXT TEXT ,
  78. constraint JOB_EXEC_CTX_FK foreign key (JOB_EXECUTION_ID)
  79. references BATCH_JOB_EXECUTION(JOB_EXECUTION_ID)
  80. ) ENGINE=InnoDB;
  81. CREATE TABLE BATCH_STEP_EXECUTION_SEQ (
  82. ID BIGINT NOT NULL,
  83. UNIQUE_KEY CHAR(1) NOT NULL,
  84. constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
  85. ) ENGINE=InnoDB;
  86. INSERT INTO BATCH_STEP_EXECUTION_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_STEP_EXECUTION_SEQ);
  87. CREATE TABLE BATCH_JOB_EXECUTION_SEQ (
  88. ID BIGINT NOT NULL,
  89. UNIQUE_KEY CHAR(1) NOT NULL,
  90. constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
  91. ) ENGINE=InnoDB;
  92. INSERT INTO BATCH_JOB_EXECUTION_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_JOB_EXECUTION_SEQ);
  93. CREATE TABLE BATCH_JOB_SEQ (
  94. ID BIGINT NOT NULL,
  95. UNIQUE_KEY CHAR(1) NOT NULL,
  96. constraint UNIQUE_KEY_UN unique (UNIQUE_KEY)
  97. ) ENGINE=InnoDB;
  98. INSERT INTO BATCH_JOB_SEQ (ID, UNIQUE_KEY) select * from (select 0 as ID, '0' as UNIQUE_KEY) as tmp where not exists(select * from BATCH_JOB_SEQ);

1.4 Student建表SQL及表数据:

  1. CREATE TABLE `student` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `name` varchar(20) NOT NULL,
  4. `age` int(11) NOT NULL,
  5. `sex` varchar(20) NOT NULL,
  6. `address` varchar(100) NOT NULL,
  7. `cid` int(11) NOT NULL,
  8. PRIMARY KEY (`id`) USING BTREE
  9. ) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8;

Student表中数据:


二、创建项目

2.1 创建Spring Boot项目:

2.2 填写项目名、包名等信息:

2.3 勾选依赖项

勾选如下红框标注的依赖项:

2.4 完成创建

点击Finish完成项目的创建:

2.5 Pom.xml依赖

项目最终依赖:

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-batch</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-data-jpa</artifactId>
  9. </dependency>
  10. <dependency>
  11. <groupId>org.springframework.boot</groupId>
  12. <artifactId>spring-boot-starter-web</artifactId>
  13. </dependency>
  14. <dependency>
  15. <groupId>mysql</groupId>
  16. <artifactId>mysql-connector-java</artifactId>
  17. <scope>runtime</scope>
  18. </dependency>
  19. <dependency>
  20. <groupId>org.projectlombok</groupId>
  21. <artifactId>lombok</artifactId>
  22. <optional>true</optional>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-starter-test</artifactId>
  27. <scope>test</scope>
  28. </dependency>
  29. <dependency>
  30. <groupId>org.springframework.batch</groupId>
  31. <artifactId>spring-batch-test</artifactId>
  32. <scope>test</scope>
  33. </dependency>
  34. </dependencies>

2.6 SpringBoot配置文件:

  1. spring:
  2. datasource:
  3. driver-class-name: com.mysql.cj.jdbc.Driver
  4. url: jdbc:mysql://127.0.0.1:3306/springbatch?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&autoReconnect=true
  5. hikari:
  6. password: password
  7. username: root
  8. jpa:
  9. open-in-view: true
  10. show-sql: true
  11. hibernate:
  12. ddl-auto: update
  13. database: mysql
  14. # 禁止项目启动时运行job
  15. batch:
  16. job:
  17. enabled: false

三、基于Spring Batch的批处理Demo

3.1 Demo项目结构:

3.2 Student Entity:

  1. package org.zero.example.springbatchdemo.model;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. import javax.persistence.*;
  6. /**
  7. * student 表格的实体类
  8. *
  9. * @author 01
  10. * @date 2019-02-24
  11. **/
  12. @Data
  13. @Entity
  14. @Table(name = "student")
  15. @NoArgsConstructor
  16. @AllArgsConstructor
  17. public class Student {
  18. @Id
  19. @GeneratedValue(strategy = GenerationType.IDENTITY)
  20. private Integer id;
  21. private String name;
  22. private Integer age;
  23. private String sex;
  24. private String address;
  25. private Integer cid;
  26. }

3.3 配置Spring的线程池

批处理作业和定时任务需要多线程,因此配置Spring的线程池,代码如下:

  1. package org.zero.example.springbatchdemo.config;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  5. /**
  6. * 配置任务线程池执行器
  7. *
  8. * @author 01
  9. * @date 2019-02-24
  10. **/
  11. @Configuration
  12. public class ExecutorConfiguration {
  13. @Bean
  14. public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
  15. ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
  16. threadPoolTaskExecutor.setCorePoolSize(50);
  17. threadPoolTaskExecutor.setMaxPoolSize(200);
  18. threadPoolTaskExecutor.setQueueCapacity(1000);
  19. threadPoolTaskExecutor.setThreadNamePrefix("Data-Job");
  20. return threadPoolTaskExecutor;
  21. }
  22. }

3.4 配置作业监听器

实现一个作业监听器,批处理作业在执行前后会调用监听器的方法:

  1. package org.zero.example.springbatchdemo.task.listener;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.batch.core.BatchStatus;
  4. import org.springframework.batch.core.JobExecution;
  5. import org.springframework.batch.core.JobExecutionListener;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
  8. import org.springframework.stereotype.Component;
  9. /**
  10. * 一个简单的job监听器
  11. *
  12. * @author 01
  13. * @date 2019-02-24
  14. **/
  15. @Slf4j
  16. @Component
  17. public class JobListener implements JobExecutionListener {
  18. private final ThreadPoolTaskExecutor threadPoolTaskExecutor;
  19. private long startTime;
  20. @Autowired
  21. public JobListener(ThreadPoolTaskExecutor threadPoolTaskExecutor) {
  22. this.threadPoolTaskExecutor = threadPoolTaskExecutor;
  23. }
  24. /**
  25. * 该方法会在job开始前执行
  26. */
  27. @Override
  28. public void beforeJob(JobExecution jobExecution) {
  29. startTime = System.currentTimeMillis();
  30. log.info("job before " + jobExecution.getJobParameters());
  31. }
  32. /**
  33. * 该方法会在job结束后执行
  34. */
  35. @Override
  36. public void afterJob(JobExecution jobExecution) {
  37. log.info("JOB STATUS : {}", jobExecution.getStatus());
  38. if (jobExecution.getStatus() == BatchStatus.COMPLETED) {
  39. log.info("JOB FINISHED");
  40. threadPoolTaskExecutor.destroy();
  41. } else if (jobExecution.getStatus() == BatchStatus.FAILED) {
  42. log.info("JOB FAILED");
  43. }
  44. log.info("Job Cost Time : {}/ms", (System.currentTimeMillis() - startTime));
  45. }
  46. }

3.5 配置Job

配置一个最基本的Job,Job是真正进行批处理业务的地方。一个Job 通常由一个或多个Step组成(基本就像是一个工作流);而一个Step通常由三部分组成(读入数据:ItemReader,处理数据:ItemProcessor,写入数据:ItemWriter)。代码如下:
  1. package org.zero.example.springbatchdemo.task.job;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.batch.core.Job;
  4. import org.springframework.batch.core.Step;
  5. import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
  6. import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
  7. import org.springframework.batch.core.launch.support.RunIdIncrementer;
  8. import org.springframework.batch.item.ItemProcessor;
  9. import org.springframework.batch.item.ItemReader;
  10. import org.springframework.batch.item.ItemWriter;
  11. import org.springframework.batch.item.database.JpaPagingItemReader;
  12. import org.springframework.batch.item.database.orm.JpaNativeQueryProvider;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.stereotype.Component;
  15. import org.zero.example.springbatchdemo.model.Student;
  16. import org.zero.example.springbatchdemo.task.listener.JobListener;
  17. import javax.persistence.EntityManagerFactory;
  18. /**
  19. * 配置一个最基本的Job
  20. *
  21. * @author 01
  22. * @date 2019-02-24
  23. **/
  24. @Slf4j
  25. @Component
  26. public class DataBatchJob {
  27. /**
  28. * Job构建工厂,用于构建Job
  29. */
  30. private final JobBuilderFactory jobBuilderFactory;
  31. /**
  32. * Step构建工厂,用于构建Step
  33. */
  34. private final StepBuilderFactory stepBuilderFactory;
  35. /**
  36. * 实体类管理工工厂,用于访问表格数据
  37. */
  38. private final EntityManagerFactory emf;
  39. /**
  40. * 自定义的简单Job监听器
  41. */
  42. private final JobListener jobListener;
  43. @Autowired
  44. public DataBatchJob(JobBuilderFactory jobBuilderFactory, StepBuilderFactory stepBuilderFactory,
  45. EntityManagerFactory emf, JobListener jobListener) {
  46. this.jobBuilderFactory = jobBuilderFactory;
  47. this.stepBuilderFactory = stepBuilderFactory;
  48. this.emf = emf;
  49. this.jobListener = jobListener;
  50. }
  51. /**
  52. * 一个最基础的Job通常由一个或者多个Step组成
  53. */
  54. public Job dataHandleJob() {
  55. return jobBuilderFactory.get("dataHandleJob").
  56. incrementer(new RunIdIncrementer()).
  57. // start是JOB执行的第一个step
  58. start(handleDataStep()).
  59. // 可以调用next方法设置其他的step,例如:
  60. // next(xxxStep()).
  61. // next(xxxStep()).
  62. // ...
  63. // 设置我们自定义的JobListener
  64. listener(jobListener).
  65. build();
  66. }
  67. /**
  68. * 一个简单基础的Step主要分为三个部分
  69. * ItemReader : 用于读取数据
  70. * ItemProcessor : 用于处理数据
  71. * ItemWriter : 用于写数据
  72. */
  73. private Step handleDataStep() {
  74. return stepBuilderFactory.get("getData").
  75. // <输入对象, 输出对象> chunk通俗的讲类似于SQL的commit; 这里表示处理(processor)100条后写入(writer)一次
  76. <Student, Student>chunk(100).
  77. // 捕捉到异常就重试,重试100次还是异常,JOB就停止并标志失败
  78. faultTolerant().retryLimit(3).retry(Exception.class).skipLimit(100).skip(Exception.class).
  79. // 指定ItemReader对象
  80. reader(getDataReader()).
  81. // 指定ItemProcessor对象
  82. processor(getDataProcessor()).
  83. // 指定ItemWriter对象
  84. writer(getDataWriter()).
  85. build();
  86. }
  87. /**
  88. * 读取数据
  89. *
  90. * @return ItemReader Object
  91. */
  92. private ItemReader<? extends Student> getDataReader() {
  93. // 读取数据,这里可以用JPA,JDBC,JMS 等方式读取数据
  94. JpaPagingItemReader<Student> reader = new JpaPagingItemReader<>();
  95. try {
  96. // 这里选择JPA方式读取数据
  97. JpaNativeQueryProvider<Student> queryProvider = new JpaNativeQueryProvider<>();
  98. // 一个简单的 native SQL
  99. queryProvider.setSqlQuery("SELECT * FROM student");
  100. // 设置实体类
  101. queryProvider.setEntityClass(Student.class);
  102. queryProvider.afterPropertiesSet();
  103. reader.setEntityManagerFactory(emf);
  104. // 设置每页读取的记录数
  105. reader.setPageSize(3);
  106. // 设置数据提供者
  107. reader.setQueryProvider(queryProvider);
  108. reader.afterPropertiesSet();
  109. // 所有ItemReader和ItemWriter实现都会在ExecutionContext提交之前将其当前状态存储在其中,
  110. // 如果不希望这样做,可以设置setSaveState(false)
  111. reader.setSaveState(true);
  112. } catch (Exception e) {
  113. e.printStackTrace();
  114. }
  115. return reader;
  116. }
  117. /**
  118. * 处理数据
  119. *
  120. * @return ItemProcessor Object
  121. */
  122. private ItemProcessor<Student, Student> getDataProcessor() {
  123. return student -> {
  124. // 模拟处理数据,这里处理就是打印一下
  125. log.info("processor data : " + student.toString());
  126. return student;
  127. };
  128. }
  129. /**
  130. * 写入数据
  131. *
  132. * @return ItemWriter Object
  133. */
  134. private ItemWriter<Student> getDataWriter() {
  135. return list -> {
  136. for (Student student : list) {
  137. // 模拟写数据,为了演示的简单就不写入数据库了
  138. log.info("write data : " + student);
  139. }
  140. };
  141. }
  142. }

3.6 执行Job

通常运行Job的方式有两种:

  1. 把Job对象注入到Spring容器里,Spring Batch默认在项目启动完成后就会运行容器里配置好的Job,如果配置了多个Job也可以通过配置文件去指定。

  1. 采用定时任务去运行Job。通过调用的方式主动去运行Job,需要使用到JobLauncher中的run方法。具体代码如下:

  1. package org.zero.example.springbatchdemo.task;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.springframework.batch.core.*;
  4. import org.springframework.batch.core.launch.JobLauncher;
  5. import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
  6. import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
  7. import org.springframework.batch.core.repository.JobRestartException;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.scheduling.annotation.Scheduled;
  10. import org.springframework.stereotype.Component;
  11. import org.zero.example.springbatchdemo.task.job.DataBatchJob;
  12. /**
  13. * 简单的定时任务
  14. *
  15. * @author 01
  16. * @date 2019-02-24
  17. **/
  18. @Slf4j
  19. @Component
  20. public class TimeTask {
  21. private final JobLauncher jobLauncher;
  22. private final DataBatchJob dataBatchJob;
  23. @Autowired
  24. public TimeTask(JobLauncher jobLauncher, DataBatchJob dataBatchJob) {
  25. this.jobLauncher = jobLauncher;
  26. this.dataBatchJob = dataBatchJob;
  27. }
  28. // 定时任务,每十秒执行一次
  29. @Scheduled(cron = "0/10 * * * * ?")
  30. public void runBatch() throws JobParametersInvalidException, JobExecutionAlreadyRunningException,
  31. JobRestartException, JobInstanceAlreadyCompleteException {
  32. log.info("定时任务执行了...");
  33. // 在运行一个job的时候需要添加至少一个参数,这个参数最后会被写到batch_job_execution_params表中,
  34. // 不添加这个参数的话,job不会运行,并且这个参数在表中中不能重复,若设置的参数已存在表中,则会抛出异常,
  35. // 所以这里才使用时间戳作为参数
  36. JobParameters jobParameters = new JobParametersBuilder()
  37. .addLong("timestamp", System.currentTimeMillis())
  38. .toJobParameters();
  39. // 获取job并运行
  40. Job job = dataBatchJob.dataHandleJob();
  41. JobExecution execution = jobLauncher.run(job, jobParameters);
  42. log.info("定时任务结束. Exit Status : {}", execution.getStatus());
  43. }
  44. }

3.7 配置Spring Boot启动类

最后,在Spring Boot的启动类上加上两个注解@EnableBatchProcessing和@EnableScheduling,以开启批处理及定时任务,否则批处理和定时任务都不会执行,代码如下:

  1. package org.zero.example.springbatchdemo;
  2. import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5. import org.springframework.scheduling.annotation.EnableScheduling;
  6. /**
  7. * :@EnableBatchProcessing 用于开启批处理作业的配置
  8. * :@EnableScheduling 用于开启定时任务的配置
  9. *
  10. * @author 01
  11. * @date 2019-02-24
  12. */
  13. @EnableScheduling
  14. @EnableBatchProcessing
  15. @SpringBootApplication
  16. public class SpringBatchDemoApplication {
  17. public static void main(String[] args) {
  18. SpringApplication.run(SpringBatchDemoApplication.class, args);
  19. }
  20. }

启动项目,等待十秒,控制台输出日志如下,证明我们的批处理程序正常执行了:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/210833
推荐阅读
相关标签
  

闽ICP备14008679号