PLM项目中定时计划任务的另一种实现方式-Springboot中@scheduled注解

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语法,程序开发好后,实施人员可以根据实际场景需要自己配置出丰富多样的时间规则。

3.解决
主要采用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有个号

 

 

 

posted @ 2022-06-05 16:57  信铁寒胜  阅读(163)  评论(0编辑  收藏  举报