1.需求
PLM项目实施时候,常常需要开发一些定时任务,去定时执行一些动作,比如:
a. 每天晚上12点,执行程序去检索PLM系统一些超期或者即将到期的未完成的任务并发送提醒 邮件到任务相关负责人;
b. 每周最后一个工作日的晚上12点,执行程序去分析PLM系统本周产生的Item及任务情况, 进行一些汇总分析,并出报告发邮件给相关负责人;
c. 每天晚上12点,执行程序去检索PLM系统中需要下发到第三方系统的数据,进行数据下发;
d. 每隔1个小时,执行一次程序去检索PLM系统中一些数据做数据下发;
e. 实时轮询PLM系统中数据,发现有需要下发的数据就执行下发程序。
2.分析
实现方式一般有两种:
方法一:执行程序+windwos操作系统的定时计划功能,但复杂时间规则的不能配置出
方法二:使用程序本身的自身定时任务机制,如:
a. 基于 java.util.Timer 定时器,实现类似闹钟的定时任务;
b. 使用 Quartz、elastic-job、xxl-job 等开源第三方定时任务框架,适合分布式项目应用;
c. 使用 Spring 提供的一个注解:@Schedule,开发简单,使用比较方便,也是本文介绍的一种方式.
其中spring的@Schedule支持cron语法,程序开发好后,实施人员可以根据实际场景需要自己配置出丰富多样的时间规则。
主要采用springboot的@Schedule定时计划
3.1 初始springboot工程
工程名称:xc-springboot-demo-scheduled
3.2 创建定时任务
3.2.1.启动定时任务
首先,在项目启动类
XcSpringbootDemoScheduledApplication.java上添加@EnableScheduling注解,开启对定时任务的支持
package com.xc.springboot.demo.scheduled; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; /** * 定时程序SpringBoot入口程序 * @author 许连波 * */ @SpringBootApplication @EnableScheduling public class XcSpringbootDemoScheduledApplication { public static void main(String[] args) { SpringApplication.run(XcSpringbootDemoScheduledApplication.class, args); } }
其中 @EnableScheduling注解的作用是发现注解@Scheduled的任务并后台执行。
3.2.2.创建定时任务实现
创建定时任务实现类
XCSpringbootDemoScheduledTask.java,
定时任务类通过Spring IOC 加载,使用@Component注解,定时方法使用@Scheduled注解。
package com.xc.springboot.demo.scheduled; import java.time.LocalDateTime; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; /** * 定时任务执行程序 * @company 迅成信息 * @author 许连波 * */ @Component public class XCSpringbootDemoScheduledTask { @Scheduled(fixedRate = 3000) public void scheduledTask() { System.out.println("任务1执行时间:" + LocalDateTime.now()); } }
fixedRate 是 long 类型,表示任务执行的间隔毫秒数,以上代码中的定时任务每 3 秒执行一次。执行效果如下图
如果想创建多个定时任务(多定时任务是单线程的,一个定时任务在执行时候,得等它执行完毕了,才会执行下一个定时任务,如果想同个任务未执行完毕就执行下一次,可以加上@Async):
方法A:创建多个定时任务类
方法B:在一个类中创建多个@scheduled注解方法
多定时任务执行效果如下图
4.总结
本文主要介绍了基于 Spring Boot 内置的定时任务的配置使用,主要涉及两个注解,四个属性的配置:
a. 主程序入口 @EnableScheduling 开启定时任务
b. 定时方法上 @Scheduled 设置定时
c. cron属性:按cron规则执行
d. fixedRate 属性:以固定速率执行
e. fixedDelay 属性:上次执行完毕后延迟再执行
f. initialDelay 属性:第一次延时执行,第一次执行完毕后延迟后再次执行
@Scheduled详解
在上面的入门例子中,使用了@Scheduled(fixedRate = 3000) 注解来定义每过 3 秒执行的任务,对于 @Scheduled 的使用可以总结如下几种方式:
a. @Scheduled(fixedRate = 3000) :上一次开始执行时间点之后 3 秒再执行(fixedRate 属性:定时任务开始后再次执行定时任务的延时(需等待上次定时任务完成),单位毫秒)
b. @Scheduled(fixedDelay = 3000) :上一次执行完毕时间点之后 3 秒再执行(fixedDelay 属性:定时任务执行完成后再次执行定时任务的延时(需等待上次定时任务完成),单位毫秒)
c. @Scheduled(initialDelay = 1000, fixedRate = 3000) :第一次延迟1秒后执行,之后按fixedRate的规则每 3 秒执行一次(initialDelay 属性:第一次执行定时任务的延迟时间,需配合fixedDelay或者fixedRate来使用)
d. @Scheduled(cron="0 0 2 1 * ? *") :通过cron表达式定义规则
cron表达式中各时间元素使用空格进行分割,表达式有至少6个(也可能7个)分别表示如下含义:
a. 秒(0~59)
b. 分钟(0~59)
c. 小时(0~23)
e. 天(月)(0~31,但是你需要考虑你月的天数)
f. 月(0~11)
g. 天(星期)(1~7 1=SUN 或 SUN,MON,TUE,WED,THU,FRI,SAT)
h. 7.年份(1970-2099)
其中,常用的cron表达式有:
0 0 2 1 * ? * :表示在每月 1 日的凌晨 2 点执行
0 15 10 ? * MON-FRI :表示周一到周五每天上午 10:15 执行
0 15 10 ? 6L 2019-2020 :表示 2019-2020 年的每个月的最后一个星期五上午 10:15 执行
0 0 10,14,16 * * ? :每天上午 10 点,下午 2 点,4 点执行
0 0/30 9-17 * * ? :朝九晚五工作时间内每半小时执行
0 0 12 ? * WED :表示每个星期三中午 12 点执行
0 0 12 * * ? :每天中午 12点执行
0 15 10 ? * * :每天上午 10:15 执行
0 15 10 * * ? :每天上午 10:15 执行
0 15 10 * * ? * :每天上午 10:15 执行
0 15 10 * * ? 2019 :2019 年的每天上午 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触发
@Scheduled括弧里等号后面的内容也可以设置成变量去读取application.properties里对应内容。
如代码里写@Scheduled(cron = "${cron.downfromtc}")
application.properties定义cron.downfromtc=0 0/10 * * * ?,则实际效果相当于@Scheduled(cron = "0 0/10 * * * ?")
转自微信公众号:PLM有个号