请叫我头头哥

SpringBoot入门教程(九)定时任务Schedule

在日常项目运行中,我们总会有需求在某一时间段周期性的执行某个动作。比如每天在某个时间段导出报表,或者每隔多久统计一次现在在线的用户量。在springboot中可以有很多方案去帮我们完成定时器的工作,有Java自带的java.util.Timer类,也有强大的调度器Quartz,还有SpringBoot自带的Scheduled,今天主要说说Scheduled。

v定时器比较

框架名称Cron表达式固定间隔执行固定频率执行任务持久化难易度
TimerTask 不支持 支持 支持 不支持 一般
schedule 支持 支持 支持 不支持 简单
Quartz 支持 支持 支持 支持

在实际应用中,如果没有分布式场景(quartz 支持分布式, schedule 不支持(需要自己实现,用分布式锁),schedule跟spring结合的更好,还是很适用的。

v创建schedule工程

使用IntelliJ IDEA创建helloschedule

SpringBoot入门教程(九)定时任务Schedule

SpringBoot入门教程(九)定时任务Schedule

SpringBoot入门教程(九)定时任务Schedule

SpringBoot入门教程(九)定时任务Schedule

SpringBoot入门教程(九)定时任务Schedule

点击finish完成项目的创建。

SpringBoot入门教程(九)定时任务Schedule

为了方便演示,使用@Slf4j输出日志,添加lombok引用,@Slf4j不清楚的可以看看SpringBoot(八)配置logback日志

添加export类。

package com.task.log;

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by toutou on 2018/10/20.
 */
@Component
@Slf4j
public class export {
    @Scheduled(cron = "0 0/1 * * * ?")
    public void minuteExport(){
        log.debug("每分钟执行一次的任务:" + getDate());
    }

    @Scheduled(fixedRate = 5000)
    public void fiveSecondExport(){
        log.debug("每5秒执行一次:" + getDate());
    }

    @Scheduled(cron = "0/2 * * * * ?")
    public void twoSecondExport(){
        log.debug("每2秒执行一次:" + getDate());
    }

    @Scheduled(cron = "0 55 14 ? * *")
    public void regularTimeExport(){
        log.debug("每天上午14点55分执行:" + getDate());
    }

    private String getDate(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(new Date());
    }
}

启动类中添加@EnableScheduling注解,然后运行。

SpringBoot入门教程(九)定时任务Schedule

查看IntelliJ IDEA控制台日志和物理文件日志

SpringBoot入门教程(九)定时任务Schedule

SpringBoot入门教程(九)定时任务Schedule

如上图,简单的定时任务输出日志搭建完成。

vcron详细说明

cron表达式,有专门的语法,而且感觉有点绕人,不过简单来说,大家记住一些常用的用法即可,特殊的语法可以单独去查。

cron一共有7位,但是最后一位是年,可以留空,所以我们可以写6位:

第一位,表示秒,取值0-59
第二位,表示分,取值0-59
第三位,表示小时,取值0-23
第四位,日期天/日,取值1-31
第五位,日期月份,取值1-12
第六位,星期,取值1-7,星期一,星期二...,注:不是第1周,第二周的意思 另外:1表示星期天,2表示星期一。
第七位,年份,可以留空,取值1970-2099

cron中,还有一些特殊的符号,含义如下:

(*)星号:可以理解为每的意思,每秒,每分,每天,每月,每年...
(?)问号:问号只能出现在日期和星期这两个位置,表示这个位置的值不确定,每天3点执行,所以第六位星期的位置,我们是不需要关注的,就是不确定的值。同时:日期和星期是两个相互排斥的元素,通过问号来表明不指定值。比如,1月10日,比如是星期1,如果在星期的位置是另指定星期二,就前后冲突矛盾了。
(-)减号:表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12
(,)逗号:表达一个列表值,如在星期字段中使用“1,2,4”,则表示星期一,星期二,星期四
(/)斜杠:如:x/y,x是开始值,y是步长,比如在第一位(秒) 0/15就是,从0秒开始,每15秒,最后就是0,15,30,45,60    另:*/y,等同于0/y

附表:

"0 0 12 * * ?" 每天中午12点触发 
"0 15 10 ? * *" 每天上午10:15触发 
"0 15 10 * * ?" 每天上午10:15触发 
"0 15 10 * * ? *" 每天上午10:15触发 
"0 15 10 * * ? 2005" 2005年的每天上午10:15触发 
"0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发 
"0 0/5 14 * * ?" 在每天下午2点到下午2:55期间的每5分钟触发 
"0 0/5 14,18 * * ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 
"0 0-5 14 * * ?" 在每天下午2点到下午2:05期间的每1分钟触发 
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发 
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发 
"0 15 10 15 * ?" 每月15日上午10:15触发 
"0 15 10 L * ?" 每月最后一日的上午10:15触发 
"0 15 10 ? * 6L" 每月的最后一个星期五上午10:15触发 
"0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发
"0 15 10 ? * 6#3" 每月的第三个星期五上午10:15触发 
每隔5秒执行一次:*/5 * * * * ?
每隔1分钟执行一次:0 */1 * * * ?
每天23点执行一次:0 0 23 * * ?
每天凌晨1点执行一次:0 0 1 * * ?
每月1号凌晨1点执行一次:0 0 1 1 * ?
每月最后一天23点执行一次:0 0 23 L * ?
每周星期天凌晨1点实行一次:0 0 1 ? * L

crontab 表达式在线生成https://tool.lu/crontab/

其他参考资料:

v源码地址

https://github.com/toutouge/javademosecond/tree/master/hellospringboot


作  者:请叫我头头哥
出  处:http://www.cnblogs.com/toutou/
关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

posted @ 2018-11-04 22:14  请叫我头头哥  阅读(20987)  评论(1编辑  收藏  举报
//Setting ico for cnblogs