作者: 追梦 1819
相信大家对定时任务很熟悉, 其重要性也不言而喻. 定时发短信, 定时批量操作, 定时统计数据等, 都离不开定时任务. 本文将讲解定时任务在 SpringBoot 项目中的应用.
版本信息
- JDK:1.8
- SpringBoot :2.0.1.RELEASE
- maven:3.3.9
- IDEA:2019.1.1
- quartz:2.3.0
定时任务实现方式
JDK 自带的 Timer
Timer 是 Java 自带的定时任务类. 可以用作比较简单的定时任务. 通常用的不多. 下面以一个小的示例展示其用法.
SpringBoot 集成的 schedule
这种方式是 SpringBoot 集成的, 使用很简单.
首先, 引入 SpringBoot 的基础 jar:
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter</artifactId>
- </dependency>
然后再启动类中添加注解 @EnableScheduling 即可开启 SpringBoot 定时任务:
- @SpringBootApplication
- @EnableScheduling
- public class TimedTaskDemoApplication {
- public static void main(String[] args) {
- SpringApplication.run(TimedTaskDemoApplication.class, args);
- }
- }
下面根据 @Scheduled 的不同属性创建几个任务:
任务一:
- @Component
- public class FirstTask {
- /**
- * cron 表达式
- */
- // @Scheduled(cron = "0/2 * * * * *")
- @Scheduled(cron="${cron.schedule}")
- public void run(){
- System.out.println("这是创建的第一个定时任务");
- }
- }
作几点说明:
cron 表达式是 @Scheduled 的属性之一, 其值可以直接设置为 cron 表达式;
@Scheduled(cron="${cron.schedule}")
是动态读取 application.properties 配置文件中的 cron 表达式. 例如项目中的一个需求是每天凌晨 0 点执行, 但是对于测试人员来说, 不可能等到凌晨测试. 动态读取可以帮助解决该问题.
任务二:
- @Component
- public class SecondTask {
- /**
- * 上一次执行完毕时间点之后多长时间再执行 (ms)
- */
- @Scheduled(fixedDelay = 2000)
- public void run(){
- System.out.println("这是创建的第二个定时任务");
- }
- }
任务三:
- @Component
- public class ThirdTask {
- /**
- * 与 fixedDelay 功能相同, 上一次执行完毕时间点之后多长时间再执行 (ms), 区别是: 1, 时间是字符串; 2, 支持占位符
- */
- // @Scheduled(fixedDelayString = "2000")
- @Scheduled(fixedDelayString = "${time.fixedDelay}")
- public void run(){
- System.out.println("这是创建的第三个定时任务");
- }
- }
上面的三个任务列举了 @Scheduled 注解的三个参数. 其实除此之外, 查看 @Scheduled 的源码可知, 还有其余的几个参数:
fixedRate: 上一次开始执行时间点之后多长时间再执行;
fixedRateString: 上一次开始执行时间点之后多长时间再执行;
fixedRateString: 与 fixedRate 意思相同, 只是使用字符串的形式. 唯一不同的是支持占位符;
initialDelay: 第一次延迟多长时间后再执行;
initialDelayString: 与 initialDelay 意思相同, 只是使用字符串的形式. 唯一不同的是支持占位符;
整合 Quartz
如果以上的方式都无法满足项目的需求, 则可以试试 Quartz 调度框架. 它功能的强大以及使用无需多说了. 此处我们看看 Quartz 在 SpringBoot 中的使用.
创建项目, 引入 Quartz 调度框架启动器:
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-quartz</artifactId>
- </dependency>
需要注意版本信息, 如果 SpringBoot 版本是 2.0 以后的版本, 直接引入 Quartz 启动器即可. 但是如果是 2.0 以前的版本, 需要引入以下 jar 包:
- <dependency>
- <groupId>org.quartz-scheduler</groupId>
- <artifactId>quartz</artifactId>
- <version>2.3.0</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context-support</artifactId>
- </dependency>
下面创建任务了:
- public class QuartzTask extends QuartzJobBean {
- @Override
- protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
- System.out.println(new Date());
- }
- }
任务需要继承 QuartzJobBean 抽象类, 并重写 executeInternal 方法.
第三步, 创建 quartz 配置类, 添加 @Configuration 注解:
- @Configuration
- public class QuartzConfig {
- @Bean
- public JobDetail testQuartzTask() {
- return JobBuilder.newJob(QuartzTask.class).withIdentity("quartztask").storeDurably().build();
- }
- @Bean
- public Trigger testQuartzTrigger2() {
- //cron 方式, 每隔 5 秒执行一次
- return TriggerBuilder.newTrigger().forJob(testQuartzTask())
- .withIdentity("quartztask")
- .withSchedule(CronScheduleBuilder.cronSchedule("*/5 * * * * ?"))
- .build();
- }
- }
上面的示例是使用 cron 表达式, 当然也可以是固定时间间隔. 本节是阐述 SpringBoot 和 Quartz 的整合, 不作 Quartz 的详细使用. 感兴趣的读者可以登录 Quartz 的官网 http://www.quartz-scheduler.org/ 或者中文官网 https://www.w3cschool.cn/quartz_doc/ 自行研究.
总结
定时任务的实现方式有很多种, 除了上面说到的几种方式, 还有利用线程池实现定时任务, 有的系统是通过 Liunx 实现定时任务. 总之, 定时任务的实现方式多种多样, 其方式要根据项目的实际情况而选. 切不可为了实现而实现.
来源: https://www.cnblogs.com/yanfei1819/p/11076555.html