Spring Boot 2.X 学习日记——搞定定时任务
文章目录
前言
在实际生产中,我们往往会碰到这样一种场景:在指定的某一时刻,需要执行一段业务代码。这时候,有经验的开发者,一定会想到定时任务这个概念。那么在Spring Boot中,我们该如何使用定时任务呢?
下面笔者将简单的聊聊Spring Boot中的定时任务。
实现
在Spring Boot中,我们实现定时任务的功能,通常是有两种方案:
**Spring Task:**Spring3.0 以后新增了task
,一个轻量级的Quartz
,功能够用,用法简单。
Quartz: 功能最为强大的调度器,可以让程序在指定时间执行,也可以按照某一个频度执行,它还可以动态开关,但是配置起来比较复杂。现如今开源社区中已经很多基于Quartz 实现的分布式定时任务项目
(xxl-job、elastic-job)。
Spring Task
添加依赖
spring-boot-starter-web
中,已经包括了spring-context
的依赖,而定时任务的相关类就在其下面的org.springframework.scheduling
包中,所以我们无需额外添加依赖。
实现方式
Spring Task
中实现定时任务,主要是通过我们在相关的业务方法上加上**@Scheduled**的注解。
Scheduled.java
public @interface Scheduled {
/**
* cron表达式
*/
String cron() default "";
/**
* 时区
*/
String zone() default "";
/**
* 两次执行时间间隔(A任务结束时间-B任务开始时间)
*/
long fixedDelay() default -1;
/**
* 两次执行时间间隔(A任务结束时间-B任务开始时间)
*/
String fixedDelayString() default "";
/**
* 两次执行时间间隔(A任务开始时间-B任务开始时间)
*/
long fixedRate() default -1;
/**
* 两次执行时间间隔(A任务开始时间-B任务开始时间)
*/
String fixedRateString() default "";
/**
* 第一次执行延迟时间,只是做延迟的设定,与fixedDelay关系密切,配合使用,相辅相成。
*/
long initialDelay() default -1;
/**
* 第一次执行延迟时间,只是做延迟的设定,与fixedDelay关系密切,配合使用,相辅相成。
*/
String initialDelayString() default "";
}
然后,还有个重要的注解就是**@Async**,这个注解主要是将串行执行改为并行执行。假设某业务代码(@Scheduled(cron = "0/1 * * * * *")
第一次执行的时间为2019-04-01 20:30:55
,该业务代码需要执行3000
ms,如果是串行化执行的话,下一次调用该代码的时间就为2019-04-01 20:30:59
;而并行的话,下一次调用该代码的时间就为2019-04-01 20:30:56
。
具体编码
ScheduledTestService.java
package com.boot.demo.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
@Service
public class ScheduledTestService {
private static final Logger logger = LoggerFactory.getLogger(ScheduledTestService.class);
@Scheduled(cron = "0/1 * * * * *")
@Async
public void schedule1() throws InterruptedException {
logger.info("定时任务 : {},执行时间 : {}","schedule1", LocalDateTime.now());
Thread.sleep(3000l);
}
@Scheduled(cron = "0/1 * * * * *")
public void schedule2() throws InterruptedException {
logger.info("定时任务 : {},执行时间 : {}","schedule2", LocalDateTime.now());
Thread.sleep(3000l);
}
}
BootApplication.java
package com.boot.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* 测试定时任务
* Author : Ivan
**/
@SpringBootApplication
@EnableScheduling //必需,否则无法加载定时任务
@EnableAsync //不加则无法使用@Async注解
public class BootApplication {
public static void main(String[] args) {
SpringApplication.run(BootApplication.class,args);
}
}
测试
启动项目,观察日志如下