Spring Boot 定时任务与调度系统
Spring Boot 定时任务与调度系统
29.1 学习目标与重点提示
学习目标:掌握Spring Boot定时任务与调度系统的核心概念与使用方法,包括定时任务的定义与特点、调度系统的定义与特点、Spring Boot与定时任务的集成、Spring Boot的实际应用场景,学会在实际开发中处理定时任务与调度系统问题。
重点:定时任务的定义与特点、调度系统的定义与特点、Spring Boot与定时任务的集成、Spring Boot的实际应用场景。
29.2 定时任务与调度系统概述
定时任务与调度系统是Java开发中的重要组件。
29.2.1 定时任务的定义
定义:定时任务是指按照预定的时间间隔或时间点执行的任务,用于处理周期性的业务逻辑。
作用:
- 提高系统的自动化程度。
- 减少人工干预。
- 提高系统的可靠性。
常见的定时任务:
- 数据库备份。
- 数据清洗。
- 报表生成。
- 邮件发送。
✅ 结论:定时任务是指按照预定的时间间隔或时间点执行的任务,作用是提高系统的自动化程度、减少人工干预、提高系统的可靠性。
29.2.2 调度系统的定义
定义:调度系统是一种用于管理和调度定时任务的系统,用于监控任务的执行情况、处理任务的失败和重试。
作用:
- 实现任务的调度。
- 实现任务的监控。
- 实现任务的失败和重试。
常见的调度系统:
- Apache Airflow:Apache Airflow是一种开源的调度系统。
- Quartz:Quartz是一种开源的调度系统。
- Spring Task:Spring Task是Spring Boot内置的定时任务调度系统。
- Elastic Job:Elastic Job是一种开源的调度系统。
✅ 结论:调度系统是一种用于管理和调度定时任务的系统,作用是实现任务的调度、监控、失败和重试。
29.3 Spring Boot与定时任务的集成
Spring Boot与定时任务的集成是Java开发中的重要内容。
29.3.1 集成Spring Task的步骤
定义:集成Spring Task的步骤是指使用Spring Boot与Spring Task集成的方法。
步骤:
- 创建Spring Boot项目。
- 添加所需的依赖。
- 配置定时任务。
- 创建定时任务类。
- 测试应用。
示例:
pom.xml文件中的依赖:
<dependencies><!-- Web依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 测试依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>application.properties文件中的配置:
# 服务器端口 server.port=8080 定时任务类:
importorg.springframework.scheduling.annotation.Scheduled;importorg.springframework.stereotype.Component;importjava.text.SimpleDateFormat;importjava.util.Date;@ComponentpublicclassProductScheduledTask{privateSimpleDateFormat dateFormat =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");@Scheduled(fixedRate =5000)// 每隔5秒执行一次publicvoidfixedRateTask(){System.out.println("固定频率任务执行时间:"+ dateFormat.format(newDate()));// 处理固定频率任务的业务逻辑processFixedRateTask();}@Scheduled(fixedDelay =5000)// 任务完成后间隔5秒执行下一次publicvoidfixedDelayTask(){System.out.println("固定延迟任务执行时间:"+ dateFormat.format(newDate()));// 处理固定延迟任务的业务逻辑processFixedDelayTask();}@Scheduled(cron ="0 0/1 * * * ?")// 每分钟执行一次publicvoidcronTask(){System.out.println("Cron任务执行时间:"+ dateFormat.format(newDate()));// 处理Cron任务的业务逻辑processCronTask();}privatevoidprocessFixedRateTask(){// 模拟处理固定频率任务的业务逻辑try{Thread.sleep(2000);System.out.println("固定频率任务处理完成:"+ dateFormat.format(newDate()));}catch(InterruptedException e){ e.printStackTrace();}}privatevoidprocessFixedDelayTask(){// 模拟处理固定延迟任务的业务逻辑try{Thread.sleep(2000);System.out.println("固定延迟任务处理完成:"+ dateFormat.format(newDate()));}catch(InterruptedException e){ e.printStackTrace();}}privatevoidprocessCronTask(){// 模拟处理Cron任务的业务逻辑try{Thread.sleep(2000);System.out.println("Cron任务处理完成:"+ dateFormat.format(newDate()));}catch(InterruptedException e){ e.printStackTrace();}}}应用启动类:
importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.scheduling.annotation.EnableScheduling;@SpringBootApplication@EnableSchedulingpublicclassScheduledTaskApplication{publicstaticvoidmain(String[] args){SpringApplication.run(ScheduledTaskApplication.class, args);}}测试类:
importorg.junit.jupiter.api.Test;importorg.springframework.boot.test.context.SpringBootTest;importstaticorg.assertj.core.api.Assertions.assertThat;@SpringBootTestclassScheduledTaskApplicationTests{@TestvoidcontextLoads(){assertThat(true).isTrue();}}✅ 结论:集成Spring Task的步骤包括创建Spring Boot项目、添加所需的依赖、配置定时任务、创建定时任务类、测试应用。
29.3.2 集成Quartz的步骤
定义:集成Quartz的步骤是指使用Spring Boot与Quartz集成的方法。
步骤:
- 创建Spring Boot项目。
- 添加所需的依赖。
- 配置Quartz。
- 创建定时任务类。
- 测试应用。
示例:
pom.xml文件中的依赖:
<dependencies><!-- Web依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Quartz依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency><!-- 测试依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>application.properties文件中的配置:
# 服务器端口 server.port=8080 # Quartz配置 spring.quartz.job-store-type=jdbc spring.quartz.jdbc.initialize-schema=always spring.quartz.scheduler-name=MyScheduler spring.quartz.properties.org.quartz.threadPool.threadCount=10 定时任务类:
importorg.quartz.Job;importorg.quartz.JobExecutionContext;importorg.quartz.JobExecutionException;importorg.springframework.stereotype.Component;importjava.text.SimpleDateFormat;importjava.util.Date;@ComponentpublicclassProductQuartzJobimplementsJob{privateSimpleDateFormat dateFormat =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");@Overridepublicvoidexecute(JobExecutionContext jobExecutionContext)throwsJobExecutionException{System.out.println("Quartz任务执行时间:"+ dateFormat.format(newDate()));// 处理Quartz任务的业务逻辑processQuartzTask();}privatevoidprocessQuartzTask(){// 模拟处理Quartz任务的业务逻辑try{Thread.sleep(2000);System.out.println("Quartz任务处理完成:"+ dateFormat.format(newDate()));}catch(InterruptedException e){ e.printStackTrace();}}}Quartz配置类:
importorg.quartz.*;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;@ConfigurationpublicclassQuartzConfig{@BeanpublicJobDetailproductJobDetail(){returnJobBuilder.newJob(ProductQuartzJob.class).withIdentity("productJob").storeDurably().build();}@BeanpublicTriggerproductTrigger(){returnTriggerBuilder.newTrigger().forJob(productJobDetail()).withIdentity("productTrigger").withSchedule(CronScheduleBuilder.cronSchedule("0 0/1 * * * ?"))// 每分钟执行一次.build();}}控制器类:
importorg.quartz.*;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.*;@RestController@RequestMapping("/api/quartz")publicclassQuartzController{@AutowiredprivateScheduler scheduler;@PostMapping("/start")publicStringstartJob(){try{JobDetail jobDetail =productJobDetail();Trigger trigger =productTrigger(); scheduler.scheduleJob(jobDetail, trigger);return"任务已启动";}catch(SchedulerException e){ e.printStackTrace();return"任务启动失败";}}@PostMapping("/stop")publicStringstopJob(){try{TriggerKey triggerKey =newTriggerKey("productTrigger"); scheduler.pauseTrigger(triggerKey);JobKey jobKey =newJobKey("productJob"); scheduler.deleteJob(jobKey);return"任务已停止";}catch(SchedulerException e){ e.printStackTrace();return"任务停止失败";}}privateJobDetailproductJobDetail(){returnJobBuilder.newJob(ProductQuartzJob.class).withIdentity("productJob").storeDurably().build();}privateTriggerproductTrigger(){returnTriggerBuilder.newTrigger().forJob(productJobDetail()).withIdentity("productTrigger").withSchedule(CronScheduleBuilder.cronSchedule("0 0/1 * * * ?")).build();}}应用启动类:
importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublicclassQuartzApplication{publicstaticvoidmain(String[] args){SpringApplication.run(QuartzApplication.class, args);}}测试类:
importorg.junit.jupiter.api.Test;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.context.SpringBootTest;importorg.springframework.boot.test.web.client.TestRestTemplate;importorg.springframework.boot.web.server.LocalServerPort;importstaticorg.assertj.core.api.Assertions.assertThat;@SpringBootTest(webEnvironment =SpringBootTest.WebEnvironment.RANDOM_PORT)classQuartzApplicationTests{@LocalServerPortprivateint port;@AutowiredprivateTestRestTemplate restTemplate;@TestvoidcontextLoads(){}@TestvoidtestStartJob(){String response = restTemplate.postForObject("http://localhost:"+ port +"/api/quartz/start",null,String.class);assertThat(response).contains("任务已启动");}@TestvoidtestStopJob(){String response = restTemplate.postForObject("http://localhost:"+ port +"/api/quartz/stop",null,String.class);assertThat(response).contains("任务已停止");}}✅ 结论:集成Quartz的步骤包括创建Spring Boot项目、添加所需的依赖、配置Quartz、创建定时任务类、测试应用。
29.4 Spring Boot的实际应用场景
在实际开发中,Spring Boot定时任务与调度系统的应用场景非常广泛,如:
- 实现数据库备份的定时任务。
- 实现数据清洗的定时任务。
- 实现报表生成的定时任务。
- 实现邮件发送的定时任务。
示例:
importorg.springframework.scheduling.annotation.Scheduled;importorg.springframework.stereotype.Component;importjava.text.SimpleDateFormat;importjava.util.Date;@ComponentclassProductScheduledTask{privateSimpleDateFormat dateFormat =newSimpleDateFormat("yyyy-MM-dd HH:mm:ss");@Scheduled(fixedRate =5000)publicvoidfixedRateTask(){System.out.println("固定频率任务执行时间:"+ dateFormat.format(newDate()));processFixedRateTask();}@Scheduled(fixedDelay =5000)publicvoidfixedDelayTask(){System.out.println("固定延迟任务执行时间:"+ dateFormat.format(newDate()));processFixedDelayTask();}@Scheduled(cron ="0 0/1 * * * ?")publicvoidcronTask(){System.out.println("Cron任务执行时间:"+ dateFormat.format(newDate()));processCronTask();}privatevoidprocessFixedRateTask(){try{Thread.sleep(2000);System.out.println("固定频率任务处理完成:"+ dateFormat.format(newDate()));}catch(InterruptedException e){ e.printStackTrace();}}privatevoidprocessFixedDelayTask(){try{Thread.sleep(2000);System.out.println("固定延迟任务处理完成:"+ dateFormat.format(newDate()));}catch(InterruptedException e){ e.printStackTrace();}}privatevoidprocessCronTask(){try{Thread.sleep(2000);System.out.println("Cron任务处理完成:"+ dateFormat.format(newDate()));}catch(InterruptedException e){ e.printStackTrace();}}}@SpringBootApplication@EnableSchedulingpublicclassScheduledTaskApplication{publicstaticvoidmain(String[] args){SpringApplication.run(ScheduledTaskApplication.class, args);}}// 测试类@SpringBootTestclassScheduledTaskApplicationTests{@TestvoidcontextLoads(){assertThat(true).isTrue();}}输出结果:
- 控制台输出:
固定频率任务执行时间:2023-06-01 10:00:00
固定频率任务处理完成:2023-06-01 10:00:02
固定延迟任务执行时间:2023-06-01 10:00:02
固定延迟任务处理完成:2023-06-01 10:00:04
Cron任务执行时间:2023-06-01 10:01:00
Cron任务处理完成:2023-06-01 10:01:02
✅ 结论:在实际开发中,Spring Boot定时任务与调度系统的应用场景非常广泛,需要根据实际问题选择合适的定时任务和调度系统。
总结
本章我们学习了Spring Boot定时任务与调度系统,包括定时任务的定义与特点、调度系统的定义与特点、Spring Boot与定时任务的集成、Spring Boot的实际应用场景,学会了在实际开发中处理定时任务与调度系统问题。其中,定时任务的定义与特点、调度系统的定义与特点、Spring Boot与定时任务的集成、Spring Boot的实际应用场景是本章的重点内容。从下一章开始,我们将学习Spring Boot的其他组件、微服务等内容。