模拟场景:有时候,你需要每天某个点或者每周、每个月让程序做一些事情,如调用接口获取数据,比如生成数据的报表,或者统计一些数据之类,你除了可以在数据库创建存储过程,还可以写Java定时任务。
O的K,接着上一篇的开发环境。《SpringBoot从入门到放弃》之第(十)篇
我们创建一个定时任务的测试类 MyScheduledTask:
package com.test.web;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
public class MyScheduledTask {
int n = 0;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Scheduled(cron = "*/3 * * * * *")
public void myTask(){
System.out.println("米老鼠偷吃了第 "+(++n)+" 个面包,偷吃时间:"+sdf.format(new Date()));
}
}
说明:@Component 注解泛指各类组件,当你无法清晰的判断这个类属于什么组件(比如@Controller、@Services)时,可以使用@Component ,这样就能让Spring容器来管理这个类。
然后,在启动的类里加上 @EnableScheduling 注解:
package com.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableScheduling;
//@MapperScan("com.test.dao") //在启动类添加扫描 Mybatis 层的注解或者在 Dao 层添加 @Mapper 注解
@SpringBootApplication
@EnableCaching
@EnableScheduling
public class MyTest02Application {
public static void main(String[] args) {
SpringApplication.run(MyTest02Application.class, args);
}
}
启动测试,查看控制台输出信息,每间隔 3 秒执行一次 myTask 方法:
@Scheduled 标注在方法上,让此方法成为定时任务执行的入口。
cron 俗称“七子表达式”:秒、分、时、日、月、周(周几,星期几)、年(可选)
* 星号表示在这个域上包含所有合法的值。
? 号只能用在日和周域上,但是不能在这两个域上同时使用。你可以认为 ? 字符是"我并不关心在该域上是什么值。" 这不同于星号,星号是指示着该域上的每一个值。? 是说不为该域指定值。
, 逗号用来在给某个域上指定一个值列表的
斜杠 (/) 是用于时间表的递增的
中划线 (-) 用于指定一个范围
常用的一些表达式例子:
①每隔3秒执行一次:*/3 * * * * ?
②每分钟执行一次:0 */1 * * * ?
③每天23点执行一次:0 0 23 * * ?
④每月3号的上午11:15触发:0 15 11 3 * ?
⑤每月最后一天23点执行一次:0 0 23 L * ?
⑥每周星期天凌晨1点执行一次:0 0 1 ? * L
⑦在每小时的20分、25分、35分执行一次:0 20,25,35 * * * ?
⑧每天0点、13点、18点都执行一次:0 0 0,13,18 * * ?
此外,@Scheduled 还可以使用其它表达式,如:
① @Scheduled(fixedDelay = 3000):上一次执行完毕之后 3 秒再执行(单位:毫秒)
② @Scheduled(fixedRate = 5000):上一次开始执行的时间点之后 5 秒再执行(单位:毫秒)
③ @Scheduled(initialDelay = 2000,fixedRate = 5000):第一次延迟 2 秒之后执行,之后按 fixedRate 的规则每 5 秒执行一次。