SpringBoot中实现@Scheduled动态定时任务

 更新时间:2024年01月29日 09:34:15   作者:roseduan  
SpringBoot中的@Scheduled注解为定时任务提供了一种很简单的实现,本文主要介绍了SpringBoot中实现@Scheduled动态定时任务,具有一定的参考价值,感兴趣的可以了解一下

1. 概论

Spring Boot 中的 @Scheduled 注解为定时任务提供了一种很简单的实现,只需要在注解中加上一些属性,例如 fixedRate、fixedDelay、cron(最常用)等等,并且在启动类上面加上 @EnableScheduling 注解,就可以启动一个定时任务了。

但是在某些情况下,并没有这么简单,例如项目部署上线之后,我们可能会修改定时任务的执行时间,并且停止、重启定时任务等,因为定时任务是直接写死在程序中的,修改起来不是非常的方便。所以,简单记录一下自己的一些解决方案,仅供参考。

2. 在配置文件中设置参数

以 cron 表达式为例,一般的做法是将 @Scheduled 的属性写在程序中的,例如这样:

@Component
public class TestTask {
    private static SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Scheduled(cron = "0/5 * * * * ?")
    public void test(){
        System.out.println(dateFmt.format(new Date()) + " : 执行定时任务");
    }
}

如果需要修改的话,我们可以将 cron 表达式配在 application.yml 中:

#application.yml中的配置
scheduled:
  cron: 0/5 * * * * ?

然后在 @Scheduled 中获取这个配置:

@Scheduled(cron = "${scheduled.cron}")
public void test(){
    System.out.println(dateFmt.format(new Date()) + " : 执行定时任务");
}

等到了线上的时候,再通过修改配置文件中的内容来进行控制。具体怎么动态的修改配置文件中的内容,后面我会专门写一篇文章来说明。

3. 如何关闭定时任务

一种方式是根据实际的需求,设置一个很久之后的时间再执行,例如明年的某个时间点,你可能会想何不设置一个已经过去的时间(例如 2012 年),但是很遗憾,@Scheduled 并不支持设置年份。

另外 Spring Boot 2.1 以上的版本还提供了一种停止定时任务的方案,就是在 cron 中配置 “-” 即可,你也可以在配置文件中设置这个符号:

#application.yml中的配置
scheduled:
  cron: "-"

注意这里必须加上一个双引号,因为在 application.yml 中, - 是一个特殊的字符。

4. 为定时任务设置开关

如果嫌上面这种方式比较死板,可以尝试另一种,给定时任务加上开关的方案,在配置文件中配置一个 boolean 属性,如果是 true 的话,就开启定时任务,否则不开启。

#application.yml中的配置
scheduled:
  cron: 0/5 * * * * ?
enable:
  scheduled: true

然后我们可以使前面说到的 @Conditional 注解来实现这个功能,如果你还不了解,可以看我这篇文章:浅谈 Spring Boot 中的 @Conditional 注解

其实 @Scheduled 注解,是被一个叫做 ScheduledAnnotationBeanPostProcessor 的类所拦截的,所以我们可以根据配置,决定是否创建这个 bean,如果没有这个 bean,@Scheduled 就不会被拦截,那么定时任务肯定不会执行了,有了这个思路,实现起来就很简单了。需要注意的是:这种方式,启动类上面的 @EnableScheduling 需要去掉。

然后创建一个 ScheduledCondtion 类,内容如下:

public class ScheduledCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //读取配置中的属性
        return Boolean.valueOf(context.getEnvironment().getProperty("enable.scheduled"));
    }
}

这个类的功能很简单,就是去读取配置,然后返回一个 boolean 值。

然后创建一个配置类 ScheduledConfig ,内容如下:

@Configuration
public class ScheduledConfig {

    @Conditional(ScheduledCondition.class)
    @Bean
    public ScheduledAnnotationBeanPostProcessor processor() {
        return new ScheduledAnnotationBeanPostProcessor();
    }
}

这个配置,就是以 ScheduledCondtion 为条件,决定是否创建 bean。然后,启动项目,定时任务就会执行,如果我们将配置修改为 false,则不会执行。

这样的话,我们就能够很容易的启动或者关闭定时任务了,并且也可以实时修改 cron 表达式的值。

到此这篇关于SpringBoot中实现@Scheduled动态定时任务的文章就介绍到这了,更多相关SpringBoot @Scheduled动态定时内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java8 实现提取集合对象的每个属性

    java8 实现提取集合对象的每个属性

    这篇文章主要介绍了java8 实现提取集合对象的每个属性方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • java中的反射及其优点说明

    java中的反射及其优点说明

    这篇文章主要介绍了java中的反射及其优点说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • 简单了解java中int和Integer的区别

    简单了解java中int和Integer的区别

    这篇文章主要介绍了简单了解java中int和Integer的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • JavaWeb文件上传下载实例讲解(酷炫的文件上传技术)

    JavaWeb文件上传下载实例讲解(酷炫的文件上传技术)

    在Web应用系统开发中,文件上传功能是非常常用的功能,今天来主要讲讲JavaWeb中的文件上传功能的相关技术实现,本文给大家介绍的非常详细,具有参考借鉴价值,感兴趣的朋友一起看看吧
    2016-11-11
  • Java 程序里transient关键字使用方法示例

    Java 程序里transient关键字使用方法示例

    这篇文章主要为大家介绍了Java 程序里transient关键字使用方法示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • Java中String类常用的各种方法(示例详解)

    Java中String类常用的各种方法(示例详解)

    本文介绍了Java中String类的常用方法,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2025-01-01
  • 关于Java中的 JSP 详解

    关于Java中的 JSP 详解

    JSP 代表 Java 服务器页面。它是一种在应用服务器端使用的编程工具。JSP 基本上用于支持平台–独立和动态的方法来构建 Web 依赖的应用程序。JSP 页面类似于 ASP 页面,因为它们是在服务器上编译的,而不是在用户的 Web 浏览器上进行编译。下面来看看文章的详细介绍内容
    2021-11-11
  • Java判断IP地址为内网IP还是公网IP的方法

    Java判断IP地址为内网IP还是公网IP的方法

    这篇文章主要介绍了Java判断IP地址为内网IP还是公网IP的方法,针对tcp/ip协议中保留的三个私有地址进行判断分析,是比较实用的技巧,需要的朋友可以参考下
    2015-01-01
  • Java不能真正泛型的原因是什么?

    Java不能真正泛型的原因是什么?

    今天我来给大家讲一下,Java 不能实现真正泛型的原因是什么?感兴趣的朋友可以看一下,如果能给你到来一些帮助,请关注小编的其他内容
    2021-08-08
  • Java中的复合数据类型

    Java中的复合数据类型

    这篇文章主要介绍了Java中的复合数据类型,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10

最新评论