草庐IT

18《Spring Boot 入门教程》Spring Boot 定时任务

木子教程 2023-03-28 原文

1. 前言

定时任务绝对是实际项目中的刚需。

  • 我们想监控一个重点服务的运行状态,可以每隔 1 分钟调用下该服务的心跳接口,调用失败时即发出告警信息;
  • 我们想每天凌晨的时候,将所有商品的库存置满,以免早上忘记添加库存影响销售;
  • 我们想在每个周六的某个时段进行打折促销。

在以上的案例中,或者是指定时间间隔,或者是指定时间节点,按设定的任务进行某种操作,这就是定时任务了。

在 Spring Boot 中实现定时任务简单而灵活,本节我们来体验下。

2. Spring Task 定时任务

Spring Task 是 Spring Boot 内置的定时任务模块,可以满足大部分的定时任务场景需求。

通过为方法添加一个简单的注解,即可按设定的规则定时执行该方法。

下面就演示下 Spring Boot 中使用 Spring Task 的具体方法。

2.1 使用 Spring Initializr 创建项目

Spring Boot 版本选择 2.2.5 ,Group 为 com.imooc , Artifact 为 spring-boot-task ,生成项目后导入 Eclipse 开发环境。

2.2 开启定时任务

在启动类上添加 @EnableScheduling 注解,开启定时任务功能。

实例:

@SpringBootApplication
@EnableScheduling // 开启定时任务
public class SpringBootTaskApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootTaskApplication.class, args);
    }
}

2.3 通过注解设定定时任务

新建 MySpringTask 任务类,添加 @Component 注解注册 Spring 组件,定时任务方法需要在 Spring 组件类才能生效。

注意类中方法添加了 @Scheduled 注解,所以会按照 @Scheduled 注解参数指定的规则定时执行。

实例:

/**
 * 任务类
 */
@Component
public class MySpringTask {
    /**
     * 每2秒执行1次
     */
    @Scheduled(fixedRate = 2000)
    public void fixedRateMethod() throws InterruptedException {
        System.out.println("fixedRateMethod:" + new Date());
        Thread.sleep(1000);
    }
}

上面例子执行情况如下,可见是每隔 2 秒执行 1 次。

fixedRateMethod:Fri May 15 22:04:52 CST 2020
fixedRateMethod:Fri May 15 22:04:54 CST 2020
fixedRateMethod:Fri May 15 22:04:56 CST 2020

实例:

/**
 * 任务类
 */
@Component
public class MySpringTask {
    /**
     * 执行结束2秒后执行下次任务
     */
    @Scheduled(fixedDelay = 2000)
    public void fixedDelayMethod() throws InterruptedException {
        System.out.println("fixedDelayMethod:" + new Date());
        Thread.sleep(1000);
    }
}

上面的例子执行情况如下,每次打印后先等待 1 秒,然后方法执行结束 2 秒后再次执行任务,所以是每 3 秒打印 1 行内容。

fixedDelayMethod:Fri May 15 22:08:26 CST 2020
fixedDelayMethod:Fri May 15 22:08:29 CST 2020
fixedDelayMethod:Fri May 15 22:08:32 CST 2020

2.4 使用 Cron 表达式

@Scheduled 也支持使用 Cron 表达式, Cron 表达式可以非常灵活地设置定时任务的执行时间。以本节开头的两个需求为例:

  • 我们想监控一个重点服务的运行状态,可以每隔 1 分钟调用下该服务的心跳接口,调用失败时即发出告警信息;
  • 我们想在每天凌晨的时候,将所有商品的库存置满,以免早上忘记添加库存影响销售。

对应的定时任务实现如下:

实例:

/**
 * 任务类
 */
@Component
public class MySpringTask {
    /**
     * 在每分钟的00秒执行
     */
    @Scheduled(cron = "0 * * * * ?")
    public void jump() throws InterruptedException {
        System.out.println("心跳检测:" + new Date());
    }
    /**
     * 在每天的00:00:00执行
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void stock() throws InterruptedException {
        System.out.println("置满库存:" + new Date());
    }
}

Cron 表达式并不难理解,从左到右一共 6 个位置,分别代表秒、时、分、日、月、星期,以秒为例:

  • 如果该位置上是 0 ,表示在第 0 秒执行;
  • 如果该位置上是 * ,表示每秒都会执行;
  • 如果该位置上是 ? ,表示该位置的取值不影响定时任务,由于月份中的日和星期可能会发生意义冲突,所以日、 星期中需要有一个配置为 ?

按照上面的理解,cron = "0 * * * * ?" 表示在每分钟的 00 秒执行、cron = "0 0 0 * * ?" 表示在每天的 00:00:00 执行。

Tips:Cron 表达式的描述能力很强,此处只是简单提及,感兴趣的同学可以自行查阅相关资料了解更多信息。

3. Quartz 定时任务

Spring Task 已经可以满足绝大多数项目对定时任务的需求,但是在企业级应用这个领域,还有更加强大灵活的 Quartz 框架可供选择。


5ebfc3f709364d9907610239.jpg

Quartz 官网介绍:企业级的任务调度框架

举个例子,当我们想根据数据库中的配置,动态地指定商品打折的时间区间时,就可以利用 Quartz 框架来实现。 OK ,接下来我们就来具体完整实现下。

3.1 使用 Spring Initializr 创建项目

Spring Boot 版本选择 2.2.5 ,Group 为 com.imooc , Artifact 为 spring-boot-quartz ,生成项目后导入 Eclipse 开发环境。

3.2 引入项目依赖

需要引入 Quartz 框架相关依赖。

实例:

        <!-- Quartz -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>

3.3 开启定时任务

同样需要,在启动类上添加 @EnableScheduling 注解,开启定时任务功能。

实例:

@SpringBootApplication
@EnableScheduling // 开启定时任务
public class SpringBootQuartzApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootQuartzApplication.class, args);
    }
}

3.4 Quartz 定时任务开发

Quartz 定时任务需要通过 Job 、 Trigger 、 JobDetail 来设置。

  • Job:具体任务操作类
  • Trigger:触发器,设定执行任务的时间
  • JobDetail:指定触发器执行的具体任务类及方法

我们先开发一个 Job 组件:

实例:

/**
 * 打折任务
 */
@Component // 注册到容器中
public class DiscountJob {
    /**
     * 执行打折
     */
    public void execute() {
        System.out.println("更新数据库中商品价格,统一打5折");
    }
}

然后在配置类中设定 Trigger 及 JobDetail 。

实例:

/**
 * 定时任务配置
 */
@Configuration
public class QuartzConfig {
    /**
     * 配置JobDetail工厂组件,生成的JobDetail指向discountJob的execute()方法
     */
    @Bean
    MethodInvokingJobDetailFactoryBean jobFactoryBean() {
        MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
        bean.setTargetBeanName("discountJob");
        bean.setTargetMethod("execute");
        return bean;
    }
    /**
     * 触发器工厂
     */
    @Bean
    CronTriggerFactoryBean cronTrigger() {
        CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
        // Corn表达式设定执行时间规则
        bean.setCronExpression("0 0 8 ? * 7");
        // 执行JobDetail
        bean.setJobDetail(jobFactoryBean().getObject());
        return bean;
    }
}

具体分析下上面的代码:

  1. 触发器设定的 Corn 表达式为 0 0 8 ? * 7 ,表示每周六的 08:00:00 执行 1 次;
  2. 触发器指定的 JobDetail 为 jobFactoryBean 工厂的一个对象,而 jobFactoryBean 指定的对象及方法为 discountJob 与 execute () ;
  3. 所以每周六的 8 点,就会运行 discountJob 组件的 execute () 方法 1 次;
  4. Corn 表达式和执行任务、方法均以参数形式存在,这就意味着我们完全可以根据文件或数据库配置动态地调整执行时间和执行的任务;
  5. 最后,周六 8 点的时候,商品都打了 5 折,别忘了促销结束的时候恢复价格啊。

4. 小结

Spring Boot 可以利用一个简单的注解,快速实现定时任务的功能。

说实话我第一次使用 @Scheduled 注解时,完全被这种开箱即用型的简洁震撼了,我的感受是:似乎不能更加简洁了。

如果感觉 Spring Task 提供的定时任务机制还不足以满足需求,Spring Boot 还可以方便地集成 Quartz 框架来帮忙。

开箱即用满足不了,还可以即插即用,确实够人性化的。

有关18《Spring Boot 入门教程》Spring Boot 定时任务的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  3. ruby-on-rails - Rails 3 I18 : translation missing: da. datetime.distance_in_words.about_x_hours - 2

    我看到这个错误:translationmissing:da.datetime.distance_in_words.about_x_hours我的语言环境文件:http://pastie.org/2944890我的看法:我已将其添加到我的application.rb中:config.i18n.load_path+=Dir[Rails.root.join('my','locales','*.{rb,yml}').to_s]config.i18n.default_locale=:da如果我删除I18配置,帮助程序会处理英语。更新:我在config/enviorments/devolpment

  4. ruby - 如何使用 RSpec::Core::RakeTask 创建 RSpec Rake 任务? - 2

    如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake

  5. ruby-on-rails - 如果我将 ruby​​ 版本 2.5.1 与 rails 版本 2.3.18 一起使用会怎样? - 2

    如果我使用ruby​​版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby​​1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更

  6. ruby-on-rails - Ruby on Rails I18n 插值 - 2

    大家好!我对我的:username字段进行了一个小的验证,它应该是4到30个字符。我写了一个验证::length=>{:within=>4..30,:message=>I18n.t('activerecord.errors.range')-我想显示一个错误各种错误的消息(不像,太长或太短),但这里有一个问题-我可以将最小值和最大值都传递给翻译,以便有类似的东西:用户名应该在4到30个字符之间。目前我有:range:"shouldbebetween%{count}and%{count}characters",这显然不起作用(只是为了检查)。是否可以从范围中获取这些值?谢谢大家的指教!

  7. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  8. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  9. 在VMware16虚拟机安装Ubuntu详细教程 - 2

    在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主

  10. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

随机推荐