springBoot中怎么创建定时任务
创始人
2024-12-23 02:02:17
0次

基于注解

pom.xml 文件不用修改,我们原本的项目就支持,其实定时器是springboot框架自带的,不用引入什么依赖。我们直接创建一个autotask 包,创建一个AutoTask类。

@EnableScheduling@Component@Slf4jpublic class AutoTask { @Scheduled(cron="*/6 * * * * ?") private void process(){  log.info("autoTask "); }}

这样一个定时器就创建啦,在项目启动后,会每隔6s 打印“autoTask”的日志。是不是很简单。主要用到的两个注解就是@EnableScheduling 和 @Scheduled。

注解@EnableScheduling 就是开启定时任务的。哪个类的中的方法想要定期执行,就在这个类上加入这个注解。当然这个这个注解也可以加在启动类上。加在启动类上表示项目中所有的类都可以创建定时任务。

@Scheduled 注解就是我们常见的定时器啦,后面的cron 就是定时任务表达式。在方法上注解,表示这个方法定期执行。

不过@Scheduled 可以进行两种配置,我们熟悉的cron ,还有一种是fixedRate。比如fixedRate=6000 表示方法每6秒钟执行一次。

我们来启动项目看一下,可以看到两个方法都在定期执行。

基于接口

上面可以看到springboot 基于注解是非常方便的。但是对于频繁变动或者一个项目中有很多的定时器那就不方便管理了。所以统一将定时器信息存放在数据库中。

DROP TABLE IF EXISTS `scheduled`;CREATE TABLE `scheduled` ( `cron_id` varchar(30) NOT NULL PRIMARY KEY, `cron_name` varchar(30) NULL, `cron` varchar(30) NOT NULL);INSERT INTO `scheduled` VALUES ('1','定时器任务一','0/6 * * * * ?');

在dao 层mapper1包下创建一个CronMapper接口,很简单的就获取cron

public interface CronMapper { @Select("select cron from scheduled where cron_id = #{id}") public String getCron(int id);}

这里我们就不写service 层了。直接在autotask 包下创建一个AutoTaskFromDB类

@Slf4j@Componentpublic class AutoTaskFromDB implements SchedulingConfigurer { @Autowired protected CronMapper cronMapper; @Override public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {  scheduledTaskRegistrar.addTriggerTask(() -> process(),    triggerContext -> {     String cron = cronMapper.getCron(1);     if (cron.isEmpty()) {      log.info("cron 为空");     }     return new CronTrigger(cron).nextExecutionTime(triggerContext);    }  ); } private void process(){  log.info("formDB "); }}

可以看到也很简单,就是实现SchedulingConfigurer 这个吧接口,addTriggerTask()是添加一个定时器。process()方法是我们需要定时执行的方法体。

CronTrigger(cron).nextExecutionTime(triggerContext) 就是从数据库读取的cron 创建定时器。

这个类我没有加上@EnableScheduling 注解,因为我在启动类上加上了,如果你们启动类上没有加,这里记得加上。

测试一下;下图可以看到三个定时任务都执行了,fromDB 是从数据库读取的。

cron

cron 用法网上有很多,也没有什么讲的这里就附带记录下

结构

cron表达式是一个字符串,分为6或7个域,每两个域之间用空格分隔,

其语法格式为:"秒域 分域 时域 日域 月域 周域 年域"

取值范围

秒域      0~59的整数      * - , /              分域      0~59的整数      * - , /              时域      0~23的整数      * - , /              日域      1~31的整数      * - , / ? L              月域      1~12的整数或JAN~DEC      * - , /              周域      1~7的整数或SUN~SAT      * - , / ? L #              年域      1970~2099的整数      * - , /

常例

每隔5秒钟执行一次      */5 * * * * ?              每隔1分钟执行一次      0 * /1 * * * ?              每天1点执行一次          0 0 1 * * ?              每天23点55分执行一次           0 55 23 * * ?              每月最后一天23点执行一次          0 0 23 L * ?              每周六8点执行一次          0 0 8 ? * L              每月最后一个周五,每隔2小时执行一次           0 0 */2 ? * 6L              每月的第三个星期五上午10:15执行一次          0 15 10 ? * 5#3              在每天下午2点到下午2:05期间的每1分钟执行          0 0-5 14 * * ?              表示周一到周五每天上午10:15执行           0 15 10 ? * 2-6              每个月的最后一个星期五上午10:15执行          0 15 10 ? * 6L              每天上午10点,下午2点,4点执行一次          0 0 10,14,16 * * ?              朝九晚五工作时间内每半小时执行一次          0 0/30 9-17 * * ?              每个星期三中午12点执行一次           0 0 12 ? * 4              每年三月的星期三的下午2:10和2:44各执行一次          0 10,44 14 ? 3 4               每月的第三个星期五上午10:15执行一次          0 15 10 ? * 6#3              每月一日凌晨2点30执行一次          0 30 2 1 * ?              每分钟的第10秒与第20秒都会执行          10,20 * * * * ?              每月的第2个星期的周5,凌晨执行          0 0 0 ? * 6#2

番外

本来这个知识点不应该放在这里讲的,但是不多,顺带写了,刚好也能做定时器。我们项目中往往有一些需求需要在项目启动的时候就执行,那这个我们怎么实现了。其实spring boot 使用起来也非常简单,只用实现 ApplicationRunner 就好了。

我们在autotask 包下创建一个AutoTaskFromSpringRunner类

@Slf4j@Componentpublic class AutoTaskFromSpringRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception {  process(); } private void process(){  log.info(" run ApplicationArguments"); }}

那这个怎么用来做定时器呢?当然是结合线程来做啦,但是这个方法其实不建议,b毕竟线程很容易出问题,但是提供一种思路:启动项目看一下,可以发现这个会在项目启动后执行,但是只会执行一次。

@Slf4j@Componentpublic class AutoTaskFromSpringRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception {  process();  new Thread(() -> {   while (true) {    process2();    try {     Thread.sleep(6000);    } catch (InterruptedException e) {     log.error("{}",e);    }   }  }).start(); } private void process(){  log.info(" run ApplicationArguments"); } private void process2(){  log.info("线程定时器"); }}

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...