Spring 中的定时任务

Spring 中使用定时任务

在 Spring 中使用定时任务非常容易,步骤如下:

  1. 第一步在启动类加上 @EnableScheduling 注解,开启对定时任务的支持。
package com.springboot.chapter13;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling // 开启对定时任务的支持
public class Chapter13Application {
   

    public static void main(String[] args) {
   
        SpringApplication.run(Chapter13Application.class, args);
    }
}
  1. 第二步在方法上加上 @Scheduled 注解,并配置配置项,编写定时逻辑。
package com.springboot.chapter13.task;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Service
public class MyTask {
   

    int num = 1;

	// 每隔 1s 执行一次
    @Scheduled(fixedRate = 1000)
    public void job1() {
   
        System.out.println("敲了 " + num + " 个 BUG!");
        num++;
    }
}

注意:别忘了在 MyTask 类标注 @Service@Component 等注解,将我们创建的 MyTask 类注入到 Spring 容器中,这样 Spring 才会去执行定时任务。

  1. 启动项目,控制台打印信息如下:
    在这里插入图片描述

上述中 @Scheduled 只是按照时间间隔执行,有时候需要指定更为具体的时间,例如,每天晚上 11:00 开始任务,或者一些任务在每周日执行。为了能够更为精确地指定任务执行的时间,所以有必要更为细致地研究 @Scheduled 的配置项。

@Scheduled 注解源码

@Target({
   ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
   
    String CRON_DISABLED = "-";

    String cron() default "";

    String zone() default "";

    long fixedDelay() default -1L;

    String fixedDelayString() default "";

    long fixedRate() default -1L;

    String fixedRateString() default "";

    long initialDelay() default -1L;

    String initialDelayString() default "";
}

@Scheduled 的配置项

配置项 类型 描述
cron String 使用表达式的方式定义任务执行时间
zone String 可以通过它设定区域时间
fixedDelay long 表示从上一个任务完成开始到下一个任务开始的间隔,单位为毫秒
fixedDelayString String 与 fixedDelay 相同,只是使用字符串,这样可以使用 SpEL 来引入配置文件的配置
initialDelay long 在 Spring IoC 容器完成初始化后,首次任务执行延迟时间,单位为毫秒
initialDelayString String 与 initialDelay 相同,只是使用字符串,这样可以使用 SpEL 来引入配置文件的配置
fixedRate long 从上一个任务开始到下一个任务开始的间隔,单位为毫秒
fixedRateString String 与 fixedRate 相同,只是使用字符串,这样可以使用 SpEL 来引入配置文件的配置

上表中的配置项除了 cron 外都比较好理解,只有 cron 是可以通过表达式更为灵活地配置运行的方式。cron 有 6~7 个空格分隔的时间元素,按顺序依次是 “ 秒分时天月星期年 ”,其中年是一个可以不配置的元素,Spring 官方也给出了对应的图解,如下所示:
在这里插入图片描述
对 Spring 官网感兴趣的话,点击下方链接直达 Spring 定时任务模块。

https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#scheduling-cron-expression

小试牛刀:

  • 0 0 0 ? * WED

这个配置表示每个星期三中午 0 点整。这个表达式需要注意的是其中的特殊字符,如 ?*,这里因为天和星期会产生定义上的冲突,所以往往会以通配符 ? 表示,它表示不指定值,而 * 则表示任意的月。除此以外还会有下表所示的其他通配符。

通配符含义

通配符 描述
* 表示任意值
? 不指定值,用于处理天和日期配置的冲突
- 指定时间区间
/ 指定时间间隔执行
L 最后的
# 第几个
, 列举多个项

cron 表达式举例

项目类型 描述
0 0 0 * * ? 每天 0 点整触发
0 15 23 ? * * 每天 23:15 触发
0 15 0 * * ? 每天 0:15 触发
0 15 10 * * ? 每天早上 10:15 触发
0 30 10 * * ? 2018 2018 年的每天早上 10:30 触发
0 * 23 * * ? 每天从 23 点开始到 23 点 59 分每分钟一次触发
0 0/3 23 * * ? 每天从 23 点开始到 23:59 分结束每 3 min 一次触发
0 0/3 20,23 * * ? 每天的 20 点至 20:59 和 23 点至 23:59 分两个时间段内每 3 min 一次触发
0 0-5 21 * * ? 每天 21:00 至 21:05 每分钟一次触发
0 10,44 14 ? 3 WED 3 月的每周三的 14:00 和 14:44 触发
0 0 23 ? * MON-FRI 每周一到周五的 23:00 触发
0 30 23 ? * 5L 2017-2020 2017 年至 2020 年的每月最后一个周五的 23:30 触发
0 15 22 ? * 5#3 每月第三周周五的 22:15 触发

小工具 -> 在线 Cron 表达式生成器:https://cron.qqe2.com

下面再通过两个实例来巩固对定时任务的理解,代码如下:

// Spring IoC 容器初始化后,第一次延迟 3 秒 , 每隔 1 秒执行一次
@Scheduled(initialDelay = 3000,fixedRate = 1000)
public void job2() {
   
    System.out.println("开始了!");
}

// 11:00 到 11:59 点每分钟执行一次
@Scheduled(cron = "0 * 11 * * ?")
public void job3() {
   
    System.out.println("睡着了没?");
}

定时任务原理

参考文章链接:https://blog.csdn.net/weixin_34452850/article/details/81127569

如上文所述,我们可以通过 @EnableScheduling 注解开启对定时任务的支持,所以我们先从 @EnableScheduling 注解开始说起。

@Target({
   ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({
   SchedulingConfiguration.class})
@Documented
public @interface EnableScheduling {
   
}

可以看到,@EnableScheduling 注解的主要功能就是通过 @Import 注解导入了 SchedulingConfiguration 配置类,@Import 注解是 Spring 提供的导入注解,可以将一个配置类或者普通的一个类初始化到 Spring 容器中,具体使用可以参考 https://blog.csdn.net/u010502101/article/details/78760032,这里不再赘述。现在我们来看 SchedulingConfiguration 配置类。

@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class SchedulingConfiguration {
   

	// 向 IOC 容器中注册一个 ScheduledAnnotationBeanPostProcessor 实例
	@Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
	@Role(
  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值