在Spring Boot中实现定时任务功能,可以通过Spring自带的定时任务调度,也可以通过集成经典开源组件Quartz实现任务调度。

一、Spring定时器

1、cron表达式方式

使用自带的定时任务,非常简单,只需要像下面这样,加上注解就好,不需要像普通定时任务框架那样继承任何定时处理接口 ,简单示例代码如下:

package com.power.demo.scheduledtask.simple;import com.power.demo.util.DateTimeUtil;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import java.util.Date;@Component
@EnableScheduling
public class SpringTaskA {/*** CRON表达式参考:http://cron.qqe2.com/**/@Scheduled(cron = "*/5 * * * * ?", zone = "GMT+8:00")private void timerCron() {try {Thread.sleep(100);} catch (Exception e) {e.printStackTrace();}System.out.println(String.format("(timerCron)%s 每隔5秒执行一次,记录日志", DateTimeUtil.fmtDate(new Date())));}}

上述代码中,在一个类上添加@EnableScheduling注解,在方法上加上@Scheduled,配置下cron表达式,一个最最简单的cron定时任务就完成了。cron表达式的各个组成部分,可以参考下面:

@Scheduled(cron = "[Seconds] [Minutes] [Hours] [Day of month] [Month] [Day of week] [Year]")

2、fixedRate和fixedDelay

@Scheduled注解除了cron表达式,还有其他配置方式,比如fixedRate和fixedDelay,下面这个示例通过配置方式的不同,实现不同形式的定时任务调度,示例代码如下:

package com.power.demo.scheduledtask.simple;import com.power.demo.util.DateTimeUtil;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import java.util.Date;@Component
@EnableScheduling
public class SpringTaskB {/*fixedRate:上一次开始执行时间点之后5秒再执行*/@Scheduled(fixedRate = 5000)public void timerFixedRate() {try {Thread.sleep(100);} catch (Exception e) {e.printStackTrace();}System.out.println(String.format("(fixedRate)现在时间:%s", DateTimeUtil.fmtDate(new Date())));}/*fixedDelay:上一次执行完毕时间点之后5秒再执行*/@Scheduled(fixedDelay = 5000)public void timerFixedDelay() {try {Thread.sleep(100);} catch (Exception e) {e.printStackTrace();}System.out.println(String.format("(fixedDelay)现在时间:%s", DateTimeUtil.fmtDate(new Date())));}/*第一次延迟2秒后执行,之后按fixedDelay的规则每5秒执行一次*/@Scheduled(initialDelay = 2000, fixedDelay = 5000)public void timerInitDelay() {try {Thread.sleep(100);} catch (Exception e) {e.printStackTrace();}System.out.println(String.format("(initDelay)现在时间:%s", DateTimeUtil.fmtDate(new Date())));}}

注意一下主要区别:

@Scheduled(fixedRate = 5000) :上一次开始执行时间点之后5秒再执行

@Scheduled(fixedDelay = 5000) :上一次执行完毕时间点之后5秒再执行

@Scheduled(initialDelay=2000, fixedDelay=5000) :第一次延迟2秒后执行,之后按fixedDelay的规则每5秒执行一次

有时候,很多项目我们都需要配置好定时任务后立即执行一次,initialDelay就可以不用配置了。

3、zone

@Scheduled注解还有一个熟悉的属性zone,表示时区,通常,如果不写,定时任务将使用服务器的默认时区;如果你的任务想在特定时区特定时间点跑起来,比如常见的多语言系统可能会定时跑脚本更新数据,就可以设置一个时区,如东八区,就可以设置为:

zone = "GMT+8:00"

二、Quartz

Quartz是应用最为广泛的开源任务调度框架之一,有很多公司都根据它实现自己的定时任务管理系统。Quartz提供了最常用的两种定时任务触发器,即SimpleTrigger和CronTrigger,本文以最广泛使用的CronTrigger为例。

1、添加依赖

        <dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.0</version></dependency>

2、配置cron表达式

示例代码需要,在application.properties文件中新增如下配置:

 cron-config

其实,我们完全可以不用配置,直接在代码里面写或者持久化在DB中然后读取也可以。

3、添加定时任务实现

任务1:

package com.power.demo.scheduledtask.quartz;import com.power.demo.util.DateTimeUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;import java.util.Date;@DisallowConcurrentExecution
public class QuartzTaskA implements Job {@Overridepublic void execute(JobExecutionContext var1) throws JobExecutionException {try {Thread.sleep(1);} catch (Exception e) {e.printStackTrace();}System.out.println(String.format("(QuartzTaskA)%s 每隔3秒执行一次,记录日志", DateTimeUtil.fmtDate(new Date())));}
}

任务2:

 QuartzTaskB

定时发送邮件任务:

 MailSendTask

实现任务看上去非常简单,继承Quartz的Job接口,重写execute方法即可。

4、集成Quartz定时任务

怎么让Spring自动识别初始化Quartz定时任务实例呢?这就需要引用Spring管理的Bean,向Spring容器暴露所必须的bean,通过定义Job Factory实现自动注入。

首先,添加Spring注入的Job Factory类:

package com.power.demo.scheduledtask.quartz.config;import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;public final class AutowireBeanJobFactory extends SpringBeanJobFactoryimplements ApplicationContextAware {private transient AutowireCapableBeanFactory beanFactory;/*** Spring提供了一种机制让你可以获取ApplicationContext,即ApplicationContextAware接口* 对于一个实现了ApplicationContextAware接口的类,Spring会实例化它的同时调用它的* public voidsetApplicationContext(ApplicationContext applicationContext) throws BeansException;接口,* 将该bean所属上下文传递给它。**/@Overridepublic void setApplicationContext(final ApplicationContext context) {beanFactory = context.getAutowireCapableBeanFactory();}@Overrideprotected Object createJobInstance(final TriggerFiredBundle bundle)throws Exception {final Object job = super.createJobInstance(bundle);beanFactory.autowireBean(job);return job;}
}

定义QuartzConfig:

package com.power.demo.scheduledtask.quartz.config;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;@Configuration
public class QuartzConfig {@Autowired@Qualifier("quartzTaskATrigger")private CronTriggerFactoryBean quartzTaskATrigger;@Autowired@Qualifier("quartzTaskBTrigger")private CronTriggerFactoryBean quartzTaskBTrigger;@Autowired@Qualifier("mailSendTrigger")private CronTriggerFactoryBean mailSendTrigger;//Quartz中的job自动注入spring容器托管的对象@Beanpublic AutowireBeanJobFactory autoWiringSpringBeanJobFactory() {return new AutowireBeanJobFactory();}@Beanpublic SchedulerFactoryBean schedulerFactoryBean() {SchedulerFactoryBean scheduler = new SchedulerFactoryBean();scheduler.setJobFactory(autoWiringSpringBeanJobFactory());  //配置Spring注入的Job类//设置CronTriggerFactoryBean,设定任务Triggerscheduler.setTriggers(quartzTaskATrigger.getObject(),quartzTaskBTrigger.getObject(),mailSendTrigger.getObject());return scheduler;}}

接着配置job明细:

package com.power.demo.scheduledtask.quartz.config;import com.power.demo.common.AppField;
import com.power.demo.scheduledtask.quartz.MailSendTask;
import com.power.demo.scheduledtask.quartz.QuartzTaskA;
import com.power.demo.scheduledtask.quartz.QuartzTaskB;
import com.power.demo.util.ConfigUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;@Configuration
public class TaskSetting {@Bean(name = "quartzTaskA")public JobDetailFactoryBean jobDetailAFactoryBean() {//生成JobDetailJobDetailFactoryBean factory = new JobDetailFactoryBean();factory.setJobClass(QuartzTaskA.class);  //设置对应的Jobfactory.setGroup("quartzTaskGroup");factory.setName("quartzTaskAJob");factory.setDurability(false);factory.setDescription("测试任务A");return factory;}@Bean(name = "quartzTaskATrigger")public CronTriggerFactoryBean cronTriggerAFactoryBean() {String cron = ConfigUtil.getConfigVal(AppField.JOB_TASKA_CRON);CronTriggerFactoryBean stFactory = new CronTriggerFactoryBean();//设置JobDetailstFactory.setJobDetail(jobDetailAFactoryBean().getObject());stFactory.setStartDelay(1000);stFactory.setName("quartzTaskATrigger");stFactory.setGroup("quartzTaskGroup");stFactory.setCronExpression(cron);return stFactory;}@Bean(name = "quartzTaskB")public JobDetailFactoryBean jobDetailBFactoryBean() {//生成JobDetailJobDetailFactoryBean factory = new JobDetailFactoryBean();factory.setJobClass(QuartzTaskB.class);  //设置对应的Jobfactory.setGroup("quartzTaskGroup");factory.setName("quartzTaskBJob");factory.setDurability(false);factory.setDescription("测试任务B");return factory;}@Bean(name = "quartzTaskBTrigger")public CronTriggerFactoryBean cronTriggerBFactoryBean() {String cron = ConfigUtil.getConfigVal(AppField.JOB_TASKB_CRON);CronTriggerFactoryBean stFactory = new CronTriggerFactoryBean();//设置JobDetailstFactory.setJobDetail(jobDetailBFactoryBean().getObject());stFactory.setStartDelay(1000);stFactory.setName("quartzTaskBTrigger");stFactory.setGroup("quartzTaskGroup");stFactory.setCronExpression(cron);return stFactory;}@Bean(name = "mailSendTask")public JobDetailFactoryBean jobDetailMailFactoryBean() {//生成JobDetailJobDetailFactoryBean factory = new JobDetailFactoryBean();factory.setJobClass(MailSendTask.class);  //设置对应的Jobfactory.setGroup("quartzTaskGroup");factory.setName("mailSendTaskJob");factory.setDurability(false);factory.setDescription("邮件发送任务");return factory;}@Bean(name = "mailSendTrigger")public CronTriggerFactoryBean cronTriggerMailFactoryBean() {String cron = ConfigUtil.getConfigVal(AppField.JOB_TASKMAIL_CRON);CronTriggerFactoryBean stFactory = new CronTriggerFactoryBean();//设置JobDetailstFactory.setJobDetail(jobDetailMailFactoryBean().getObject());stFactory.setStartDelay(1000);stFactory.setName("mailSendTrigger");stFactory.setGroup("quartzTaskGroup");stFactory.setCronExpression(cron);return stFactory;}}

最后启动你的Spring Boot定时任务应用,一个完整的基于Quartz调度的定时任务就实现好了。

本文定时任务示例中,有一个定时发送邮件任务MailSendTask,下一篇将分享Spring Boot应用中以MongoDB作为存储介质的简易邮件系统。

扩展阅读:

很多公司都会有自己的定时任务调度框架和系统,在Spring Boot中如何整合Quartz集群,实现动态定时任务配置?

参考:

http://www.cnblogs.com/vincent0928/p/6294792.html

http://www.cnblogs.com/zhenyuyaodidiao/p/4755649.html

转载于:https://www.cnblogs.com/guangliana/p/8992674.html

Spring Boot定时任务应用实践相关推荐

  1. @scheduled注解配置时间_Java开发重写Spring Boot定时任务,支持可动态调整执行时间...

    Spring Boot应该是目前最火的java开源框架了,它简化了我们创建一个web服务的过程,让我们可以在很短时间.基本零配置就可以启动一个web服务. 定时任务在我们平常的业务开发用的非常多,Sp ...

  2. Spring Boot 2.0:Docker Compose + Spring Boot + Nginx + Mysql 实践

    Spring Boot 2.0:Docker Compose + Spring Boot + Nginx + Mysql 实践 Spring Boot + Nginx + Mysql 是实际工作中最常 ...

  3. Spring Boot统一异常处理实践

    Spring Boot统一异常处理实践 参考文章: (1)Spring Boot统一异常处理实践 (2)https://www.cnblogs.com/fundebug/p/springboot-ex ...

  4. 14. Spring Boot定时任务的使用【从零开始学Spring Boot】

    [视频 & 交流平台] à SpringBoot视频 http://study.163.com/course/introduction.htm?courseId=1004329008& ...

  5. Spring Boot 缓存应用实践

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源:cnblogs.com/jeffwongishan ...

  6. Spring Boot学习笔记-实践建言

    2019独角兽企业重金招聘Python工程师标准>>> 本文延续<Spring Boot学习笔记-快速示例>,从开发指南中摘出一些实践经验可供参考.这也是笔者看到的眼前一 ...

  7. Spring Boot定时任务-Job类对象注入

    如何在我们的任务类当中,去完成其他对象的注入,Job类中注入对象,回到我们的代码当中,这个是我们编写的Job类,比如我们在Job类当中呢,我要使用到我业务下某个类的某个方法,那我们是不是要将我们业务层 ...

  8. Spring Boot定时任务-SpringBoot整合Quartz

    如何通过SpringBoot整合Quartz框架,我们首先去创建一个项目,接下来我们需要在pom文件里添加坐标,我们在使用SpringBoot整合Quartz的时候,需要添加哪些坐标呢,我们来看一下, ...

  9. Spring Boot 定时任务

    2019独角兽企业重金招聘Python工程师标准>>> 本文主要介绍了Spring Boot中使用@Scheduled创建定时任务.我们在编写Spring Boot应用中经常会遇到这 ...

最新文章

  1. informix中if else使用_面试官:代码中出现大量的if/else,需要优化,你有什么好方案?...
  2. 2021年中国科技的脚步依旧不停 我们将走得更广更深更远
  3. Java 参数数后面跟三个点(...)的含义
  4. 安装gem_Python安装第三方库及常见问题处理方法汇总
  5. Kaggle 商品销量预测季军方案出炉,应对时间序列问题有何妙招
  6. 聊聊FluxFlatMap的concurrency及prefetch参数
  7. resnet的瓶颈层的子层res4b22的命名规则
  8. unity3d C#UnityEngine API 提示中文汉化
  9. 谈谈在深圳挤公交那些事
  10. 微星主板黑苹果_AMD黑苹果主机金牌装机单
  11. 网络营销应该怎样做?巧用换IP软件
  12. uni-app项目中使用scss语法
  13. OEM/ODM/OBM
  14. OSChina 周一乱弹 —— 怎么搭讪学医的女孩,说你有病!
  15. 矩阵最大覆盖问题:最多有多少个矩阵是重合覆盖的
  16. 面试必备之深入理解自旋锁
  17. Zabbix5.0监控Nginx
  18. 斗战神服务器正在维护6,斗战神什么时候服务器数据互通_斗战神1月6日、8日服务器数据互通公告_快吧游戏...
  19. C++lesson01
  20. 图像处理系列05——Jetson Xavier NX平台JPEG硬解

热门文章

  1. PHP 打印调用堆栈信息
  2. 常量 - PHP手册笔记
  3. JavaScript正则表达式快速判断技巧
  4. ylbtech-LanguageSamples-Generics(泛型)
  5. AlertDialog具体解释
  6. Exchange Server 2010 灾难恢复
  7. BS文件夹上传操作(二) ——基本功能实现
  8. Appium+python自动化3-启动淘宝app
  9. c++网络通信(与服务器通信聊天)和c#网络通信
  10. [泰然翻译] cocos2d programming guide 场景和菜单