【SpringBoot】廿五、SpringBoot中使用Quartz管理定时任务

合集下载

SpringBoot集成Quartz实现定时任务的方法

SpringBoot集成Quartz实现定时任务的方法

SpringBoot集成Quartz实现定时任务的⽅法1 需求在我的前后端分离的实验室管理项⽬中,有⼀个功能是学⽣状态统计。

我的设计是按天统计每种状态的⽐例。

为了便于计算,在每天0点,系统需要将学⽣的状态重置,并插⼊⼀条数据作为⼀天的开始状态。

另外,考虑到学⽣的请假需求,请假的申请往往是提前做好,等系统时间⾛到实际请假时间的时候,系统要将学⽣的状态修改为请假。

显然,这两个⼦需求都可以通过定时任务实现。

在⽹上略做搜索以后,我选择了⽐较流⾏的定时任务框架Quartz。

2 QuartzQuartz是⼀个定时任务框架,其他介绍⽹上也很详尽。

这⾥要介绍⼀下Quartz⾥的⼏个⾮常核⼼的接⼝。

2.1 Scheduler接⼝Scheduler翻译成调度器,Quartz通过调度器来注册、暂停、删除Trigger和JobDetail。

Scheduler还拥有⼀个SchedulerContext,顾名思义就是上下⽂,通过SchedulerContext 我们可以获取到触发器和任务的⼀些信息。

2.2 Trigger接⼝Trigger可以翻译成触发器,通过cron表达式或是SimpleScheduleBuilder等类,指定任务执⾏的周期。

系统时间⾛到触发器指定的时间的时候,触发器就会触发任务的执⾏。

2.3 JobDetail接⼝Job接⼝是真正需要执⾏的任务。

JobDetail接⼝相当于将Job接⼝包装了⼀下,Trigger和Scheduler实际⽤到的都是JobDetail。

3 SpringBoot官⽅⽂档解读SpringBoot官⽅写了spring-boot-starter-quartz。

使⽤过SpringBoot的同学都知道这是⼀个官⽅提供的启动器,有了这个启动器,集成的操作就会被⼤⼤简化。

现在我们来看⼀看SpingBoot2.2.6官⽅⽂档,其中第4.20⼩节Quartz Scheduler就谈到了Quartz,但很可惜⼀共只有两页不到的内容,先来看看这么精华的⽂档⾥能学到些什么。

SpringBoot之旅--定时任务两种(SpringSchedule与Quartz整合)实现

SpringBoot之旅--定时任务两种(SpringSchedule与Quartz整合)实现

SpringBoot之旅--定时任务两种(SpringSchedule与Quartz整合)实现相关⽂章前⾔最近在项⽬中使⽤到定时任务,之前⼀直都是使⽤Quartz 来实现,最近看Spring 基础发现其实Spring 提供 Spring Schedule 可以帮助我们实现简单的定时任务功能。

下⾯说⼀下两种⽅式在Spring Boot 项⽬中的使⽤。

Spring Schedule 实现定时任务Spring Schedule 实现定时任务有两种⽅式 1. 使⽤XML配置定时任务, 2. 使⽤ @Scheduled 注解。

因为是Spring Boot 项⽬可能尽量避免使⽤XML配置的形式,主要说注解的形式.Spring Schedule 提供三种形式的定时任务:固定等待时间 @Scheduled(fixedDelay = 时间间隔 )@Componentpublic class ScheduleJobs {public final static long SECOND = 1 * 1000;FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");@Scheduled(fixedDelay = SECOND * 2)public void fixedDelayJob() throws InterruptedException {TimeUnit.SECONDS.sleep(2);System.out.println("[FixedDelayJob Execute]"+fdf.format(new Date()));}}固定间隔时间 @Scheduled(fixedRate = 时间间隔 )@Componentpublic class ScheduleJobs {public final static long SECOND = 1 * 1000;FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");@Scheduled(fixedRate = SECOND * 4)public void fixedRateJob() {System.out.println("[FixedRateJob Execute]"+fdf.format(new Date()));}}Corn表达式 @Scheduled(cron = Corn表达式)@Componentpublic class ScheduleJobs {public final static long SECOND = 1 * 1000;FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");@Scheduled(cron = "0/4 * * * * ?")public void cronJob() {System.out.println("[CronJob Execute]"+fdf.format(new Date()));}}Spring Boot 整合 Quartz 实现定时任务添加Maven依赖<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId></dependency>Spring Boot 整合 QuartzSpring 项⽬整合 Quartz 主要依靠添加 SchedulerFactoryBean 这个 FactoryBean ,所以在maven 依赖中添加 spring-context-support 。

SpringBoot整合Quartz定时任务的简单实例

SpringBoot整合Quartz定时任务的简单实例

SpringBoot整合Quartz定时任务的简单实例POM.XML⽂件<!-- 定时器任务 quartz需要导⼊的坐标 --><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>1.8.5</version></dependency>类似于控制器代码:package com.xiaowu.quartz.demo;import java.util.Date;import org.springframework.scheduling.annotation.Scheduled;import ponent;/***** Quartz设置项⽬全局的定时任务** @Component注解的意义泛指组件,当组件不好归类的时候,我们可以使⽤这个注解进⾏标注。

⼀般公共的⽅法我会⽤上这个注解*** @author WQ**/@Componentpublic class QuartzDemo {@Scheduled(cron = "0 0/1 * * * ?") // 每分钟执⾏⼀次public void work() throws Exception {System.out.println("执⾏调度任务:"+new Date());}@Scheduled(fixedRate = 5000)//每5秒执⾏⼀次public void play() throws Exception {System.out.println("执⾏Quartz定时器任务:"+new Date());}@Scheduled(cron = "0/2 * * * * ?") //每2秒执⾏⼀次public void doSomething() throws Exception {System.out.println("每2秒执⾏⼀个的定时任务:"+new Date());}@Scheduled(cron = "0 0 0/1 * * ? ") // 每⼀⼩时执⾏⼀次public void goWork() throws Exception {System.out.println("每⼀⼩时执⾏⼀次的定时任务:"+new Date());}}启动SpringBoot项⽬,即可。

SpringBoot中使用Quartz管理定时任务的方法

SpringBoot中使用Quartz管理定时任务的方法

SpringBoot中使⽤Quartz管理定时任务的⽅法定时任务在系统中⽤到的地⽅很多,例如每晚凌晨的数据备份,每⼩时获取第三⽅平台的 Token 信息等等,之前我们都是在项⽬中规定这个定时任务什么时候启动,到时间了便会⾃⼰启动,那么我们想要停⽌这个定时任务的时候,就需要去改动代码,还得启停服务器,这是⾮常不友好的事情直⾄遇见 Quartz,利⽤图形界⾯可视化管理定时任务,使得我们对定时任务的管理更加⽅便,快捷⼀、Quartz 简介Quartz是⼀个开源的作业调度框架,它完全由Java写成,并设计⽤于J2SE和J2EE应⽤中。

它提供了巨⼤的灵活性⽽不牺牲简单性。

你能够⽤它来为执⾏⼀个作业⽽创建简单的或复杂的调度。

它有很多特征,如:数据库⽀持,集群,插件,EJB作业预构建,JavaMail及其它,⽀持cron-like表达式等等。

⼆、开发前戏1、引⼊ maven 依赖<!-- web⽀持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Quartz 定时任务 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency>这⾥引⼊了 web 的依赖,以及 Quartz 的依赖,其余依赖请根据需求⾃⾏引⼊2、创建数据表数据模型:SQL语句:drop table if exists sys_quartz;/*==============================================================*//* Table: sys_quartz *//*==============================================================*/create table sys_quartz(id bigint(20) not null auto_increment comment '主键id',class_name varchar(32) comment '任务类名',cron_expression varchar(32) comment 'cron表达式',param varchar(32) comment '参数',descript varchar(11) comment '描述',quartz_status varchar(255) comment '启动状态(0--启动1--停⽌)',create_time datetime comment '创建时间',create_user bigint(20) comment '创建⼈',status tinyint(1) default 0 comment '状态(0--正常1--停⽤)',del_flag tinyint(1) default 0 comment '删除状态(0,正常,1已删除)',primary key (id))type = InnoDB;alter table sys_quartz comment '定时任务信息表';三、开发进⾏中1、创建实体类import com.baomidou.mybatisplus.annotation.*;import com.baomidou.mybatisplus.extension.activerecord.Model;import mon.annotation.Dict;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Data;import lombok.EqualsAndHashCode;import lombok.experimental.Accessors;import java.io.Serializable;/*** <p>* 定时任务信息表* </p>** @author lizhou* @since 2020-07-21*/@Data@EqualsAndHashCode(callSuper = false)@Accessors(chain = true)@TableName("sys_quartz")@ApiModel(value="SysQuartz对象", description="定时任务信息表")public class SysQuartz extends Model<SysQuartz> {@ApiModelProperty(value = "主键id")@TableId(value = "id", type = IdType.AUTO)private Long id;@ApiModelProperty(value = "任务类名")@TableField("class_name")private String className;@ApiModelProperty(value = "cron表达式")@TableField("cron_expression")private String cronExpression;@ApiModelProperty(value = "参数")@TableField("param")private String param;@ApiModelProperty(value = "描述")@TableField("descript")private String descript;@ApiModelProperty(value = "启动状态(0--启动1--停⽌)")@TableField("quartz_status")private Integer quartzStatus;@ApiModelProperty(value = "状态(0--正常1--停⽤)")@TableField("status")private Integer status;@ApiModelProperty(value = "删除状态(0--未删除1--已删除)")@TableField("del_flag")@TableLogicprivate Integer delFlag;@ApiModelProperty(value = "创建者")@TableField("create_user")private Long createUser;@ApiModelProperty(value = "创建时间")@TableField("create_time")private String createTime;@Overrideprotected Serializable pkVal() {return this.id;}}2、实现定时任务的 CRUD下⾯我们就要完成定时任务的新增、修改、删除、启停等基本操作了,由于不是很复杂,这⾥的代码就不贴出来了,贴⼏张图吧列表页:新增页:四、定时任务1、定时任务类我们把定时任务都放在 job 包下⾯,⼀个定时任务就是⼀个⽂件,写⼀个测试的类 TestJob.javaimport mon.utils.DateUtils;import lombok.extern.slf4j.Slf4j;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;/*** @ClassName TestJob* 测试定时任务* @Author Lizhou* @Date 2020-07-21 10:58:58**/@Slf4jpublic class TestJob implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {System.out.println("定时任务启动:" + DateUtils.getYmdHms());}}TestJob 这个类实现了 Job 接⼝,实现了 execute ⽅法,这⾥还可以接收参数这个⽂件在 com.zyxx.sbm.job 包下⾯,那么在页⾯新增定时任务的时候,就需要填写任务类名为:com.zyxx.sbm.job.TestJob cron 表达式的知识这⾥就不⼀⼀介绍了2、页⾯添加定时任务那么我们的任务类名就是:com.zyxx.sbm.job.TestJobcron 表达式:*/2 * * * * ?,表⽰两秒钟执⾏⼀次参数:我们没有传⼊参数3、后台添加定时任务package com.zyxx.sbm.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.baomidou.mybatisplus.core.metadata.IPage;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import mon.shiro.SingletonLoginUtils;import mon.utils.DateUtils;import yTableResult;import mon.utils.ResponseResult;import com.zyxx.sbm.entity.SysQuartz;import com.zyxx.sbm.mapper.SysQuartzMapper;import com.zyxx.sbm.service.SysQuartzService;import lombok.extern.slf4j.Slf4j;import ng3.StringUtils;import org.quartz.*;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;/*** <p>* 定时任务信息表服务实现类* </p>** @author lizhou* @since 2020-07-21*/@Slf4j@Servicepublic class SysQuartzServiceImpl extends ServiceImpl<SysQuartzMapper, SysQuartz> implements SysQuartzService {@Autowiredprivate Scheduler scheduler;/*** 添加定时任务*/@Overridepublic ResponseResult add(SysQuartz sysQuartz) {QueryWrapper<SysQuartz> queryWrapper = new QueryWrapper<>();queryWrapper.eq("class_name", sysQuartz.getClassName());List<SysQuartz> sysQuartzList = list(queryWrapper);if (null != sysQuartzList && !sysQuartzList.isEmpty()) {return ResponseResult.getInstance().error("该任务类名已经存在");}sysQuartz.setCreateTime(DateUtils.getYmdHms());sysQuartz.setCreateUser(SingletonLoginUtils.getUserId());save(sysQuartz);// 启动if (0 == sysQuartz.getQuartzStatus()) {this.schedulerAdd(sysQuartz.getClassName().trim(), sysQuartz.getCronExpression().trim(), sysQuartz.getParam());}return ResponseResult.getInstance().success();}/*** 添加定时任务** @param className* @param cronExpression* @param param*/@Overridepublic void schedulerAdd(String className, String cronExpression, String param) {try {// 启动调度器scheduler.start();// 构建job信息JobDetail jobDetail = JobBuilder.newJob(getClass(className).getClass()).withIdentity(className).usingJobData("param", param).build(); // 表达式调度构建器(即任务执⾏的时间)CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);// 按新的cronExpression表达式构建⼀个新的triggerCronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(className).withSchedule(scheduleBuilder).build();scheduler.scheduleJob(jobDetail, trigger);} catch (SchedulerException e) {log.error(e.getMessage());} catch (RuntimeException e) {log.error(e.getMessage());} catch (Exception e) {log.error(e.getMessage());}}/*** 删除定时任务** @param className*/@Overridepublic void schedulerDelete(String className) {try {scheduler.pauseTrigger(TriggerKey.triggerKey(className));scheduler.unscheduleJob(TriggerKey.triggerKey(className));scheduler.deleteJob(JobKey.jobKey(className));} catch (Exception e) {log.error(e.getMessage(), e);}}private static Job getClass(String className) throws Exception {Class<?> class1 = Class.forName(className);return (Job) class1.newInstance();}}需要注⼊ Scheduler 对象,使⽤该对象开启或停⽌定时任务在启动定时任务之前,我们应先删除该任务类名开启的定时任务,防⽌该任务类名已经添加过了// 删除定时任务schedulerDelete(sysQuartz.getClassName().trim());// 添加定时任务schedulerAdd(sysQuartz.getClassName().trim(), sysQuartz.getCronExpression().trim(), sysQuartz.getParam());添加定时任务,传⼊任务类名,cron 表达式,参数停⽌定时任务,只需要:scheduler.pauseJob(JobKey.jobKey(sysQuartz.getClassName().trim()));根据任务类名,停⽌定时任务即可五、开发测试启动项⽬,在管理界⾯,开启定时任务,即可在控制台看到打印的信息表⽰我们的定时任务已经启动成功了六、优化建议当我们添加了定时任务并启动后,重新启动项⽬的时候,定时任务却不会⾃动启动,这时候,我们就需要在项⽬启动的时候做⼀些事情了,也就是系统启动任务不清楚的同学可以复习⼀下之前我的博客【SpringBoot】⼗九、SpringBoot中实现启动任务import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.zyxx.sbm.entity.SysQuartz;import com.zyxx.sbm.service.SysQuartzService;import org.springframework.beans.factory.annotation.Autowired;import mandLineRunner;import org.springframework.core.annotation.Order;import ponent;import java.util.List;/*** @ClassName SystemStartTask* 项⽬启动任务--启动定时任务* @Author Lizhou* @Date 2020-07-21 12:56:56**/@Component@Order(100)public class SystemQuartzStartTask implements CommandLineRunner {@Autowiredprivate SysQuartzService sysQuartzService;@Overridepublic void run(String... args) throws Exception {// 查询启动的定时任务QueryWrapper<SysQuartz> queryWrapper = new QueryWrapper<>();queryWrapper.eq("status", 0);queryWrapper.eq("quartz_status", 0);List<SysQuartz> list = sysQuartzService.list(queryWrapper);if (null != list && !list.isEmpty()) {for (SysQuartz item : list) {// 删除定时任务sysQuartzService.schedulerDelete(item.getClassName().trim());// 添加定时任务sysQuartzService.schedulerAdd(item.getClassName().trim(), item.getCronExpression().trim(), item.getParam());}}}}从数据库查询出启动的定时任务,并将他们添加到定时任务启动中,这样项⽬⼀启动时,就会⾃动启动我们定义的定时任务了最后任务类名的正则表达式/^[a-zA-Z]+(\.([a-zA-Z])+)+$/cron 表达式的验证使⽤正则太⿇烦,可以使⽤ Quartz ⾃带验证⽅法CronExpression.isValidExpression(cron)SpringBoot 中使⽤ Quartz 管理定时任务的学习就到这⼉了,其实也并不难理解,相⽐于之前⽤的定时任务是不是好很多了呢,别忘了最后加上系统启动任务哦总结到此这篇关于SpringBoot中使⽤Quartz管理定时任务的⽂章就介绍到这了,更多相关SpringBoot管理定时任务内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。

浅谈SpringBoot集成Quartz动态定时任务

浅谈SpringBoot集成Quartz动态定时任务

浅谈SpringBoot集成Quartz动态定时任务SpringBoot⾃带schedule沿⽤的springboot少xml配置的优良传统,本⾝⽀持表达式等多种定时任务注意在程序启动的时候加上@EnableScheduling@Scheduled(cron="0/5 * * * * ?")public void job(){System.out.println("每五秒执⾏⼀次");}为什么要使⽤Quartz多任务情况下,quartz更容易管理,可以实现动态配置执⾏时间表达式:表达式⽰例:集成Quartz如何搭建springboot就不再细说,官⽹和⽹上的教程很多。

maven依赖<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.2.1</version></dependency>测试Job类SchedulerQuartzJob1和SchedulerQuartzJob2代码差不多就不⼀⼀列出package com.yvan.quartz.job;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;/*** 实现Job接⼝* @author yvan**/public class SchedulerQuartzJob1 implements Job{private void before(){System.out.println("任务开始执⾏");}@Overridepublic void execute(JobExecutionContext arg0) throws JobExecutionException {before();System.out.println("开始:"+System.currentTimeMillis());// TODO 业务System.out.println("结束:"+System.currentTimeMillis());after();}private void after(){System.out.println("任务开始执⾏");}}任务调⽤处理将其拆分成两个部分实例化Job,将任务触发器加⼊任务调度中private void startJob1(Scheduler scheduler) throws SchedulerException {// 通过JobBuilder构建JobDetail实例,JobDetail规定只能是实现Job接⼝的实例// JobDetail 是具体Job实例JobDetail jobDetail = JobBuilder.newJob(SchedulerQuartzJob1.class).withIdentity("job1", "group1").build(); // 基于表达式构建触发器CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");// CronTrigger表达式触发器继承于Trigger// TriggerBuilder ⽤于构建触发器实例CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job1", "group1").withSchedule(cronScheduleBuilder).build();scheduler.scheduleJob(jobDetail, cronTrigger);}private void startJob2(Scheduler scheduler) throws SchedulerException {JobDetail jobDetail = JobBuilder.newJob(SchedulerQuartzJob2.class).withIdentity("job2", "group2").build(); CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0/5 * * * ?");CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job2", "group2").withSchedule(cronScheduleBuilder).build();scheduler.scheduleJob(jobDetail, cronTrigger);}对外提供关于动态管理任务的⽅法/*** 开始执⾏所有任务** @throws SchedulerException*/public void startJob() throws SchedulerException {startJob1(scheduler);startJob2(scheduler);scheduler.start();}/*** 获取Job信息** @param name* @param group* @return* @throws SchedulerException*/public String getJobInfo(String name, String group) throws SchedulerException {TriggerKey triggerKey = new TriggerKey(name, group);CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);return String.format("time:%s,state:%s", cronTrigger.getCronExpression(),scheduler.getTriggerState(triggerKey).name());}/*** 修改某个任务的执⾏时间** @param name* @param group* @param time* @return* @throws SchedulerException*/public boolean modifyJob(String name, String group, String time) throws SchedulerException {Date date = null;TriggerKey triggerKey = new TriggerKey(name, group);CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);String oldTime = cronTrigger.getCronExpression();if (!oldTime.equalsIgnoreCase(time)) {CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(time);CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(name, group).withSchedule(cronScheduleBuilder).build();date = scheduler.rescheduleJob(triggerKey, trigger);}return date != null;}/*** 暂停所有任务** @throws SchedulerException*/public void pauseAllJob() throws SchedulerException {scheduler.pauseAll();}/*** 暂停某个任务** @param name* @param group* @throws SchedulerException*/public void pauseJob(String name, String group) throws SchedulerException { JobKey jobKey = new JobKey(name, group);JobDetail jobDetail = scheduler.getJobDetail(jobKey);if (jobDetail == null)return;scheduler.pauseJob(jobKey);}/*** 恢复所有任务** @throws SchedulerException*/public void resumeAllJob() throws SchedulerException {scheduler.resumeAll();}/*** 恢复某个任务** @param name* @param group* @throws SchedulerException*/public void resumeJob(String name, String group) throws SchedulerException { JobKey jobKey = new JobKey(name, group);JobDetail jobDetail = scheduler.getJobDetail(jobKey);if (jobDetail == null)return;scheduler.resumeJob(jobKey);}/*** 删除某个任务** @param name* @param group* @throws SchedulerException*/public void deleteJob(String name, String group) throws SchedulerException { JobKey jobKey = new JobKey(name, group);JobDetail jobDetail = scheduler.getJobDetail(jobKey);if (jobDetail == null)return;scheduler.deleteJob(jobKey);}完整代码package com.yvan.quartz;import java.util.Date;import org.quartz.CronScheduleBuilder;import org.quartz.CronTrigger;import org.quartz.JobBuilder;import org.quartz.JobDetail;import org.quartz.JobKey;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.TriggerBuilder;import org.quartz.TriggerKey;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import com.yvan.quartz.job.SchedulerQuartzJob1;import com.yvan.quartz.job.SchedulerQuartzJob2;/*** 任务调度处理* @author yvan**/@Configurationpublic class QuartzScheduler {// 任务调度@Autowiredprivate Scheduler scheduler;/*** 开始执⾏所有任务** @throws SchedulerException*/public void startJob() throws SchedulerException {startJob1(scheduler);startJob2(scheduler);scheduler.start();}/*** 获取Job信息** @param name* @param group* @return* @throws SchedulerException*/public String getJobInfo(String name, String group) throws SchedulerException {TriggerKey triggerKey = new TriggerKey(name, group);CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);return String.format("time:%s,state:%s", cronTrigger.getCronExpression(),scheduler.getTriggerState(triggerKey).name());}/*** 修改某个任务的执⾏时间** @param name* @param group* @param time* @return* @throws SchedulerException*/public boolean modifyJob(String name, String group, String time) throws SchedulerException { Date date = null;TriggerKey triggerKey = new TriggerKey(name, group);CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);String oldTime = cronTrigger.getCronExpression();if (!oldTime.equalsIgnoreCase(time)) {CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(time);CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(name, group).withSchedule(cronScheduleBuilder).build();date = scheduler.rescheduleJob(triggerKey, trigger);}return date != null;}/*** 暂停所有任务** @throws SchedulerException*/public void pauseAllJob() throws SchedulerException {scheduler.pauseAll();}/*** 暂停某个任务** @param name* @param group* @throws SchedulerException*/public void pauseJob(String name, String group) throws SchedulerException {JobKey jobKey = new JobKey(name, group);JobDetail jobDetail = scheduler.getJobDetail(jobKey);if (jobDetail == null)return;scheduler.pauseJob(jobKey);}/*** 恢复所有任务** @throws SchedulerException*/public void resumeAllJob() throws SchedulerException {scheduler.resumeAll();}/*** 恢复某个任务** @param name* @param group* @throws SchedulerException*/public void resumeJob(String name, String group) throws SchedulerException {JobKey jobKey = new JobKey(name, group);JobDetail jobDetail = scheduler.getJobDetail(jobKey);if (jobDetail == null)return;scheduler.resumeJob(jobKey);}/*** 删除某个任务** @param name* @param group* @throws SchedulerException*/public void deleteJob(String name, String group) throws SchedulerException {JobKey jobKey = new JobKey(name, group);JobDetail jobDetail = scheduler.getJobDetail(jobKey);if (jobDetail == null)return;scheduler.deleteJob(jobKey);}private void startJob1(Scheduler scheduler) throws SchedulerException {// 通过JobBuilder构建JobDetail实例,JobDetail规定只能是实现Job接⼝的实例// JobDetail 是具体Job实例JobDetail jobDetail = JobBuilder.newJob(SchedulerQuartzJob1.class).withIdentity("job1", "group1").build(); // 基于表达式构建触发器CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");// CronTrigger表达式触发器继承于Trigger// TriggerBuilder ⽤于构建触发器实例CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job1", "group1").withSchedule(cronScheduleBuilder).build();scheduler.scheduleJob(jobDetail, cronTrigger);}private void startJob2(Scheduler scheduler) throws SchedulerException {JobDetail jobDetail = JobBuilder.newJob(SchedulerQuartzJob2.class).withIdentity("job2", "group2").build(); CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0 0/5 * * * ?");CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("job2", "group2").withSchedule(cronScheduleBuilder).build();scheduler.scheduleJob(jobDetail, cronTrigger);}}Scheduler 注⼊这⾥采⽤监听spring容器加载完毕后事件,启动任务调⽤将Scheduler交给spring初始化管理package com.yvan.quartz;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.quartz.SchedulerFactory;import org.quartz.impl.StdSchedulerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.ApplicationListener;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.event.ContextRefreshedEvent;@Configurationpublic class ApplicationStartQuartzJobListener implements ApplicationListener<ContextRefreshedEvent>{@Autowiredprivate QuartzScheduler quartzScheduler;/*** 初始启动quartz*/@Overridepublic void onApplicationEvent(ContextRefreshedEvent event) {try {quartzScheduler.startJob();System.out.println("任务已经启动...");} catch (SchedulerException e) {e.printStackTrace();}}/*** 初始注⼊scheduler* @return* @throws SchedulerException*/@Beanpublic Scheduler scheduler() throws SchedulerException{SchedulerFactory schedulerFactoryBean = new StdSchedulerFactory();return schedulerFactoryBean.getScheduler();}}封装API这⾥封装的API主要是为了⽅便动态管理执⾏任务,当然依赖这些接⼝也可以做⼀个界⾯来更直观的操作管理任务,这个就不再赘述。

SpringBoot三种定时任务实现方式

SpringBoot三种定时任务实现方式

SpringBoot三种定时任务实现方式在Spring Boot项目中,实现定时任务是常见需求。

Spring Boot提供了多种灵活的方式来实现定时任务,包括基于注解的方式、基于接口的方式以及使用外部任务调度工具等。

定时任务作为一种系统调度工具,在一些需要有定时作业的系统中应用广泛,如每逢某个时间点统计数据、在将来某个时刻执行某些动作...定时任务在主流开发语言均提供相应的API供开发者调用,在Java中,实现定时任务有很多种方式,原生的方式实现一个完整定时任务需要由Timer、TimerTask两个类,Timer 是定时器类,用来按计划开启后台线程执行指定任务,TimerTask一个抽象类,它的子类代表一个可以被Timer计划的任务。

除此之外,还可以用ScheduledExecutorService类或者使用第三方jar库Quartz,其中Quartz是一个优秀的定时任务框架,发展至今已经非常成熟,以致后来其他的定时任务框架的核心思想或底层大多源于Quartz。

springboot作为Java的一种开发框架,在springboot项目中实现定时任务不仅可以使用Java提供的原生方式,还可以使用springboot提供的定时任务API。

本文将详细介绍三种常用的Spring Boot定时任务实现方式,并提供相应的例子代码。

1. 基于注解的方式(@Scheduled)使用@Scheduled注解是实现Spring Boot定时任务最简单直接的方式。

首先,你需要在Spring Boot的启动类或者配置类上添加@EnableScheduling注解来启用定时任务支持。

然后,在需要定时执行的方法上添加@Scheduled注解,并指定cron表达式或固定间隔。

例子代码:在上面的代码中,@Scheduled注解分别使用了cron表达式和固定频率(fixedRate)两种方式来定义定时任务。

需要注意的是,@EnableScheduling 注解只需要在Spring Boot的启动类或配置类上添加一次。

SpringBoot中的定时任务与Quartz的整合

SpringBoot中的定时任务与Quartz的整合

SpringBoot中的定时任务与Quartz的整合SpringBoot集成Quartz定时任务Quartz : 就是在指定的时间执⾏⼀次或者循环执⾏,在项⽬的开发中有时候会需要的, 还是很有⽤的.SpringBoot内置的定时1. 添加依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency>2. 启动类上添加注解@SpringBootApplication@EnableSchedulingpublic class SpringbootQuartzApplication {}3. 创建定时执⾏的任务类(两种⽅式)⽅式⼀:@Componentpublic class SchedulerTask {private int count = 0;/*** @Author Smith* @Description 设置没6秒执⾏⼀次* @Date 14:23 2019/1/24* @Param* @return void**/@Scheduled(cron = "*/6 * * * * ?")private void process(){System.out.println("this is scheduler task running " + (count++));}}⽅式⼆:@Componentpublic class SchedulerTask2 {private static final SimpleDateFormat dateFormat =new SimpleDateFormat("HH:mm:ss");/*** @Author Smith* @Description 设置没6秒执⾏⼀次* @Date 14:22 2019/1/24* @Param* @return void**/@Scheduled(fixedRate = 6000)private void process(){System.out.println("now time is " + dateFormat.format(new Date()));}}参数说明@Scheduled 参数可以接受两种定时的设置,⼀种是我们常⽤的 cron="*/6 * * * * ?",⼀种是 fixedRate = 6000,两种都可表⽰固定周期执⾏定时任务。

SpringBoot实现quartz定时任务可视化管理功能

SpringBoot实现quartz定时任务可视化管理功能

SpringBoot实现quartz定时任务可视化管理功能前⾔在实际框架或产品开发过程中,springboot中集成quarzt⽅式基本是以job和trigger的bean对象⽅式直接硬编码完成的,例如以下代码⽰例。

对于系统内定义的所有定时任务类型,具体执⾏类,执⾏策略,运⾏状态都没有⼀个动态全局的管理,所有决定将quartz做成可视化配置管理,便于统⼀管理,也降低了使⽤门槛,只需要关⼼job类的实现即可@Beanpublic JobDetail SMSJobDetail() {return JobBuilder.newJob(SMSJob.class).withIdentity("SMSJob").storeDurably().build();}// 把jobDetail注册到trigger上去@Beanpublic Trigger myJobTrigger() {SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever();return TriggerBuilder.newTrigger().forJob(SMSJobDetail()).withIdentity("myJobTrigger").withSchedule(scheduleBuilder).build();}表结构⽤于存储quartz配置DROP TABLE IF EXISTS `f_quartztask`;CREATE TABLE `f_quartztask` (`TaskID` varchar(50) NOT NULL,`TaskName` varchar(200) DEFAULT NULL,`TaskType` int(11) DEFAULT NULL,`TaskTag` varchar(100) DEFAULT NULL,`JobClassPath` varchar(200) DEFAULT NULL,`ExecutePeroid` int(11) DEFAULT NULL,`ExecuteUnit` int(11) DEFAULT NULL,`CornExpress` varchar(200) DEFAULT NULL,`Enviroment` varchar(50) DEFAULT NULL,`TaskStatus` int(11) DEFAULT NULL,`SortNum` int(11) DEFAULT NULL,`Remark` varchar(500) DEFAULT NULL,PRIMARY KEY (`TaskID`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;枚举类public class QuartzEnum {public enum TaskType implements IConvertEnumToCodeItem {Cycle(10, "循环任务"), Corn(20, "Corn表达式任务");private int _value;private String _name;private TaskType(int value, String name) {set_value(value);set_name((name));}public int get_value() {return _value;}public void set_value(int _value) {this._value = _value;}public String get_name() {return _name;}public void set_name(String _name) {this._name = _name;}@Overridepublic String toString() {return _name;}@Overridepublic String getCodeName() {return "Quartz任务类别";}}public enum ExecuteUnit implements IConvertEnumToCodeItem {Second(10, "秒"), Minute(20, "分"), Hour(30, "时");private int _value;private String _name;private ExecuteUnit(int value, String name) {set_value(value);set_name((name));}public int get_value() {return _value;}public void set_value(int _value) {this._value = _value;}public String get_name() {return _name;}public void set_name(String _name) {this._name = _name;}@Overridepublic String toString() {return _name;@Overridepublic String getCodeName() {return "Quartz间隔单位";}}public enum TaskStatus implements IConvertEnumToCodeItem {Open(10, "开启"), Close(20, "关闭");private int _value;private String _name;private TaskStatus(int value, String name) {set_value(value);set_name((name));}public int get_value() {return _value;}public void set_value(int _value) {this._value = _value;}public String get_name() {return _name;}public void set_name(String _name) {this._name = _name;}@Overridepublic String toString() {return _name;}@Overridepublic String getCodeName() {return "Quartz任务状态";}}public enum TaskEnviroment implements IConvertEnumToCodeItem {All("全部", "全部"), Dev("dev", "开发环境"), Pro("pro", "正式环境");private String _value;private String _name;private TaskEnviroment(String value, String name) {set_value(value);set_name((name));}public String get_value() {return _value;}public void set_value(String _value) {this._value = _value;}public String get_name() {return _name;}public void set_name(String _name) {this._name = _name;}@Overridepublic String toString() {return _name;}@Overridepublic String getCodeName() {return "Quartz任务执⾏环境";}}}QuartzFactory⽀持Job类注bean⼊对象@Componentpublic class QuartzFactory extends AdaptableJobFactory {@Autowiredprivate AutowireCapableBeanFactory capableBeanFactory;@Overrideprotected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { // 调⽤⽗类的⽅法Object jobInstance = super.createJobInstance(bundle);// 进⾏注⼊capableBeanFactory.autowireBean(jobInstance);return jobInstance;}}QuartzConfig注⼊QuartzFactory对象@Configurationpublic class QuartzConfig {@Autowiredprivate QuartzFactory quartzFactory;@Beanpublic SchedulerFactoryBean schedulerFactoryBean(){SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setJobFactory(quartzFactory);//将job实例化,能够操作进⾏Spring 注⼊return schedulerFactoryBean;}QuartzUtil定时任务动态添加/删除操作类,initQuartzTask⽅法在系统启动时执⾏,根据配置⾃动开启相关符合条件的任务@Componentpublic class QuartzUtil {@Autowiredprivate SchedulerFactoryBean schedulerFactoryBean;@Autowiredprivate F_QuartzTaskService quartzTaskService;@Value("${spring.profiles.active}")private String active;private static String JOB_GROUP_NAME = "DEFAULT_JOB_GROUP_NAME";private static String TRIGGER_GROUP_NAME = "DEFAULT_TRIGGER_GROUP_NAME";public void initQuartzTask() {List<F_QuartzTaskDO> openTaskList = quartzTaskService.selectAllList();if(openTaskList.size()>0){openTaskList = openTaskList.stream().filter(a -> a.getTaskStatus() == QuartzEnum.TaskStatus.Open.get_value() &&(a.getEnviroment().equals(QuartzEnum.TaskEnviroment.All.get_name()) || a.getEnviroment().equals(active))).collect(Collectors.toList());}for (F_QuartzTaskDO taskDO : openTaskList) {try {Class<Job> jobClass = (Class<Job>) Class.forName(taskDO.getJobClassPath());if (taskDO.getTaskType() == QuartzEnum.TaskType.Cycle.get_value()) {addIntervalJob(taskDO.getTaskTag(), jobClass, taskDO.getExecutePeroid(), taskDO.getExecuteUnit());} else {addCornJob(taskDO.getTaskTag(), jobClass, taskDO.getCornExpress());}} catch (Exception e) {e.printStackTrace();}}if (openTaskList.size() > 0) {System.out.println("扫描并初始化开启quartz定时任务成功,任务数量:" + openTaskList.size() + "个");}}public void startTask( F_QuartzTaskDO taskDO){try {Class<Job> jobClass = (Class<Job>) Class.forName(taskDO.getJobClassPath());if (taskDO.getTaskType() == QuartzEnum.TaskType.Cycle.get_value()) {addIntervalJob(taskDO.getTaskTag(), jobClass, taskDO.getExecutePeroid(), taskDO.getExecuteUnit());} else {addCornJob(taskDO.getTaskTag(), jobClass, taskDO.getCornExpress());}} catch (Exception e) {e.printStackTrace();}}//增加定时任务任务public void addIntervalJob(String jobName, Class<? extends Job> cls, int peroid, int timeUnit) {try {SimpleScheduleBuilder scheduleBuilder = null;if (timeUnit == QuartzEnum.ExecuteUnit.Second.get_value()) {scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(peroid).repeatForever();} else if (timeUnit == QuartzEnum.ExecuteUnit.Minute.get_value()) {scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInMinutes(peroid).repeatForever();} else if (timeUnit == QuartzEnum.ExecuteUnit.Hour.get_value()) {scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInHours(peroid).repeatForever();}Scheduler sched = schedulerFactoryBean.getScheduler();JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).storeDurably().build();Trigger trigger = TriggerBuilder.newTrigger().forJob(jobDetail).withIdentity(jobName, TRIGGER_GROUP_NAME).withSchedule(scheduleBuilder).build(); sched.scheduleJob(jobDetail, trigger);if (!sched.isShutdown()) {sched.start(); // 启动}} catch (Exception e) {throw new RuntimeException(e);}}//增加corn表达式任务public void addCornJob(String jobName, Class<? extends Job> cls, String cornExpress) {try {Scheduler sched = schedulerFactoryBean.getScheduler();JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build();CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger().withIdentity(jobName, TRIGGER_GROUP_NAME).withSchedule(CronScheduleBuilder.cronSchedule(cornExpress)).build();sched.scheduleJob(jobDetail, trigger);if (!sched.isShutdown()) {sched.start(); // 启动}} catch (Exception e) {throw new RuntimeException(e);}}//停⽌任务public void deleteJob(String jobName) {try {Scheduler sched = schedulerFactoryBean.getScheduler();TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);sched.pauseTrigger(triggerKey); // 停⽌触发器sched.unscheduleJob(triggerKey);// 移除触发器sched.deleteJob(jobKey); // 删除任务} catch (Exception e) {throw new RuntimeException(e);}}}界⾯展⽰到此这篇关于SpringBoot实现quartz定时任务可视化管理的⽂章就介绍到这了,更多相关SpringBoot 定时任务可视化内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。

springboot整合Quartz实现动态配置定时任务

springboot整合Quartz实现动态配置定时任务

springboot整合Quartz实现动态配置定时任务版权声明:本⽂为博主原创⽂章,转载请注明出处。

https:///liuchuanhong1/article/details/60873295前⾔在我们⽇常的开发中,很多时候,定时任务都不是写死的,⽽是写到数据库中,从⽽实现定时任务的动态配置,下⾯就通过⼀个简单的⽰例,来实现这个功能。

⼀、新建⼀个springboot⼯程,并添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><!-- 为了⽅便测试,此处使⽤了内存数据库 --><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.2.1</version><exclusions><exclusion><artifactId>slf4j-api</artifactId><groupId>org.slf4j</groupId></exclusion></exclusions></dependency><dependency><!-- 该依赖必加,⾥⾯有sping对schedule的⽀持 --><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId></dependency>⼆、配置⽂件application.properties# 服务器端⼝号server.port=7902# 是否⽣成ddl语句spring.jpa.generate-ddl=false# 是否打印sql语句spring.jpa.show-sql=true# ⾃动⽣成ddl,由于指定了具体的ddl,此处设置为nonespring.jpa.hibernate.ddl-auto=none# 使⽤H2数据库spring.datasource.platform=h2# 指定⽣成数据库的schema⽂件位置spring.datasource.schema=classpath:schema.sql# 指定插⼊数据库语句的脚本位置spring.datasource.data=classpath:data.sql# 配置⽇志打印信息logging.level.root=INFO.hibernate=INFO.hibernate.type.descriptor.sql.BasicBinder=TRACE.hibernate.type.descriptor.sql.BasicExtractor=TRACE.itmuch=DEBUG三、Entity类package com.chhliu.springboot.quartz.entity;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;@Entitypublic class Config {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;@Columnprivate String cron;/*** @return the id*/public Long getId() {return id;}……此处省略getter和setter⽅法……}四、任务类package com.chhliu.springboot.quartz.entity;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.EnableScheduling;import ponent;@Configuration@Component // 此注解必加@EnableScheduling // 此注解必加public class ScheduleTask {private static final Logger LOGGER = LoggerFactory.getLogger(ScheduleTask.class);public void sayHello(){("Hello world, i'm the king of the world");}}五、Quartz配置类由于springboot追求零xml配置,所以下⾯会以配置Bean的⽅式来实现package com.chhliu.springboot.quartz.entity;import org.quartz.Trigger;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.quartz.CronTriggerFactoryBean;import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;import org.springframework.scheduling.quartz.SchedulerFactoryBean;@Configurationpublic class QuartzConfigration {/*** attention:* Details:配置定时任务*/@Bean(name = "jobDetail")public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduleTask task) {// ScheduleTask为需要执⾏的任务 MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();/** 是否并发执⾏* 例如每5s执⾏⼀次任务,但是当前任务还没有执⾏完,就已经过了5s了,* 如果此处为true,则下⼀个任务会执⾏,如果此处为false,则下⼀个任务会等待上⼀个任务执⾏完后,再开始执⾏ */jobDetail.setConcurrent(false);jobDetail.setName("srd-chhliu");// 设置任务的名字jobDetail.setGroup("srd");// 设置任务的分组,这些属性都可以存储在数据库中,在多任务的时候使⽤/** 为需要执⾏的实体类对应的对象*/jobDetail.setTargetObject(task);/** sayHello为需要执⾏的⽅法* 通过这⼏个配置,告诉JobDetailFactoryBean我们需要执⾏定时执⾏ScheduleTask类中的sayHello⽅法*/jobDetail.setTargetMethod("sayHello");return jobDetail;}/*** attention:* Details:配置定时任务的触发器,也就是什么时候触发执⾏定时任务*/@Bean(name = "jobTrigger")public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) { CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();tigger.setJobDetail(jobDetail.getObject());tigger.setCronExpression("0 30 20 * * ?");// 初始时的cron表达式tigger.setName("srd-chhliu");// trigger的namereturn tigger;}/*** attention:* Details:定义quartz调度⼯⼚*/@Bean(name = "scheduler")public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger) {SchedulerFactoryBean bean = new SchedulerFactoryBean();// ⽤于quartz集群,QuartzScheduler 启动时更新⼰存在的Jobbean.setOverwriteExistingJobs(true);// 延时启动,应⽤启动1秒后bean.setStartupDelay(1);// 注册触发器bean.setTriggers(cronJobTrigger);return bean;}}六、定时查库,并更新任务package com.chhliu.springboot.quartz.entity;import javax.annotation.Resource;import org.quartz.CronScheduleBuilder;import org.quartz.CronTrigger;import org.quartz.JobDetail;import org.quartz.Scheduler;import org.quartz.SchedulerException;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.EnableScheduling;import org.springframework.scheduling.annotation.Scheduled;import ponent;import com.chhliu.springboot.quartz.repository.ConfigRepository;@Configuration@EnableScheduling@Componentpublic class ScheduleRefreshDatabase {@Autowiredprivate ConfigRepository repository;@Resource(name = "jobDetail")private JobDetail jobDetail;@Resource(name = "jobTrigger")private CronTrigger cronTrigger;@Resource(name = "scheduler")private Scheduler scheduler;@Scheduled(fixedRate = 5000) // 每隔5s查库,并根据查询结果决定是否重新设置定时任务public void scheduleUpdateCronTrigger() throws SchedulerException {CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());String currentCron = trigger.getCronExpression();// 当前Trigger使⽤的String searchCron = repository.findOne(1L).getCron();// 从数据库查询出来的System.out.println(currentCron);System.out.println(searchCron);if (currentCron.equals(searchCron)) {// 如果当前使⽤的cron表达式和从数据库中查询出来的cron表达式⼀致,则不刷新任务} else {// 表达式调度构建器CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(searchCron);// 按新的cronExpression表达式重新构建triggertrigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey()).withSchedule(scheduleBuilder).build();// 按新的trigger重新设置job执⾏scheduler.rescheduleJob(cronTrigger.getKey(), trigger);currentCron = searchCron;}}}六、相关脚本1、data.sqlinsert into config(id,cron) values(1,'0 0/2 * * * ?'); # 每2分钟执⾏⼀次定时任务2、schema.sqldrop table config if exists;create table config(id bigint generated by default as identity,cron varchar(40),primary key(id));六、运⾏测试测试结果如下:(Quartz默认的线程池⼤⼩为10)0 30 20 * * ?0 0/2 * * * ?2017-03-08 18:02:00.025 INFO 5328 --- [eduler_Worker-1] c.c.s.quartz.entity.ScheduleTask : Hello world, i'm the king of the world2017-03-08 18:04:00.003 INFO 5328 --- [eduler_Worker-2] c.c.s.quartz.entity.ScheduleTask : Hello world, i'm the king of the world2017-03-08 18:06:00.002 INFO 5328 --- [eduler_Worker-3] c.c.s.quartz.entity.ScheduleTask : Hello world, i'm the king of the world2017-03-08 18:08:00.002 INFO 5328 --- [eduler_Worker-4] c.c.s.quartz.entity.ScheduleTask : Hello world, i'm the king of the world从上⾯的⽇志打印时间来看,我们实现了动态配置,最初的时候,任务是每天20:30执⾏,后⾯通过动态刷新变成了每隔2分钟执⾏⼀次。

SpringBoot中定时任务的3种实现方式

SpringBoot中定时任务的3种实现方式

SpringBoot中定时任务的3种实现⽅式Ref定时任务的实现⽅式⽅式1:基于java.util.Timer定时器,实现类似闹钟的定时任务⽅式2:使⽤ Quartz、elastic-job、xxl-job 等开源第三⽅定时任务框架,适合分布式项⽬应⽤。

该⽅式的缺点是配置复杂。

⽅式3:使⽤ Spring 提供的⼀个注解@Schedule,开发简单,使⽤⽐较⽅便。

java.util.Timer实现定时任务基于java.util.Timer定时器,实现类似闹钟的定时任务。

这种⽅式在项⽬中使⽤较少,参考如下Demo。

import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class SpringbootAppApplication {/*** main⽅法* @param args*/public static void main(String[] args) {SpringApplication.run(SpringbootAppApplication.class, args);System.out.println("Server is running ...");TimerTask timerTask = new TimerTask() {@Overridepublic void run() {System.out.println("task run:"+ new Date());}};Timer timer = new Timer();timer.schedule(timerTask,10,3000);}}复制代码ScheduledExecutorService实现定时任务该⽅法类似Timer,参考如下Demo。

public class TestScheduledExecutorService {public static void main(String[] args) {ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();/*** @param command the task to execute 任务体* @param initialDelay the time to delay first execution ⾸次执⾏的延时时间* @param period the period between successive executions 任务执⾏间隔* @param unit the time unit of the initialDelay and period parameters 间隔时间单位*/service.scheduleAtFixedRate(()->System.out.println("task ScheduledExecutorService "+new Date()), 0, 3, TimeUnit.SECONDS);service.scheduleAtFixedRate(()->System.out.println("task ScheduledExecutorService "+new Date()), 0, 3, TimeUnit.SECONDS);}}复制代码@Schedule实现定时任务Demo1. ⾸先,在项⽬启动类上添加@EnableScheduling注解,开启对定时任务的⽀持。

SpringBoot整合Quartz定时任务(持久化到数据库)

SpringBoot整合Quartz定时任务(持久化到数据库)

SpringBoot整合Quartz定时任务(持久化到数据库)背景最近在做项⽬,项⽬中有个需求:需要使⽤定时任务,这个定时任务需要即时⽣效。

查看Quartz官⽹之后发现:Quartz提供两种基本作业存储类型:RAMJobStore :RAM也就是内存,默认情况下Quartz会将任务调度存在内存中,这种⽅式性能是最好的,因为内存的速度是最快的。

不好的地⽅就是数据缺乏持久性,但程序崩溃或者重新发布的时候,所有运⾏信息都会丢失JDBC作业存储:存到数据库之后,可以做单点也可以做集群,当任务多了之后,可以统⼀进⾏管理。

关闭或者重启服务器,运⾏的信息都不会丢失。

缺点就是运⾏速度快慢取决于连接数据库的快慢。

SpringBoot集成Quartz我们也可以⾃⼰去将quartz和springBoot整合在⼀起,其实说是springBoot还不如说是sping,因为我们没有⽤到spirngboot的相关的快捷⽅式。

如果童鞋们想快速集成Quartz,⽴刻看到效果的话,可以直接往下翻,直接看SpirngBoot⾃带的Quartz插件。

但我建议⼤家还是从spring整合Quartz开始,懂的原理,⽅有收获。

Quartz初始化表JDBCJobStore works with nearly any database, it has been used widely with Oracle, PostgreSQL, MySQL, MS SQLServer, HSQLDB, and DB2. To use JDBCJobStore, you must first create a set of database tables for Quartz to use. You can find table-creation SQL scripts in the “docs/dbTables” directory of the Quartz distribution.⼤概就是⽀持这么多的数据库类型。

【spring-boot】springboot整合quartz实现定时任务

【spring-boot】springboot整合quartz实现定时任务

【spring-boot】springboot整合quartz实现定时任务在做项⽬时有时候会有定时器任务的功能,⽐如某某时间应该做什么,多少秒应该怎么样之类的。

spring⽀持多种定时任务的实现。

我们来介绍下使⽤spring的定时器和使⽤quartz定时器 1.我们使⽤spring-boot作为基础框架,其理念为零配置⽂件,所有的配置都是基于注解和暴露bean的⽅式。

2.使⽤spring的定时器: spring⾃带⽀持定时器的任务实现。

其可通过简单配置来使⽤到简单的定时任务。

@Component@Configurable@EnableSchedulingpublic class ScheduledTasks{@Scheduled(fixedRate = 1000 * 30)public void reportCurrentTime(){System.out.println ("Scheduling Tasks Examples: The time is now " + dateFormat ().format (new Date ()));}//每1分钟执⾏⼀次@Scheduled(cron = "0 */1 * * * * ")public void reportCurrentByCron(){System.out.println ("Scheduling Tasks Examples By Cron: The time is now " + dateFormat ().format (new Date ()));}private SimpleDateFormat dateFormat(){return new SimpleDateFormat ("HH:mm:ss");}}没了,没错,使⽤spring的定时任务就这么简单,其中有⼏个⽐较重要的注解: @EnableScheduling:标注启动定时任务。

springboot整合quartz集群环境实现动态定时任务配置【原】

springboot整合quartz集群环境实现动态定时任务配置【原】

springboot整合quartz集群环境实现动态定时任务配置【原】/*** 设置quartz属性** @author XW* @create_date 2016年12月28日* @return Properties*/public Properties quartzProperties() {Properties prop = new Properties();// org.quartz.scheduler.instanceName属性可为任何值,用在JDBC JobStore// 中来唯一标识实例,但是所有集群节点中必须相同。

prop.put("quartz.scheduler.instanceName", "ServerScheduler");// instanceId 属性为 AUTO即可,基于主机名和时间戳来产生实例 ID。

prop.put("org.quartz.scheduler.instanceId", "AUTO");//// Quartz内置了一个“更新检查”特性,因此Quartz项目每次启动后都会检查官网,Quartz是否存在新版本。

这个检查是异步的,不影响Quartz项目本身的启动和初始化。

// 设置org.quartz.scheduler.skipUpdateCheck的属性为true 来跳过更新检查prop.put("org.quartz.scheduler.skipUpdateCheck", "false");//prop.put("org.quartz.scheduler.jobFactory.class","org.quartz.simpl.SimpleJobFactory");// org.quartz.jobStore.class属性为 JobStoreTX,将任务持久化到数据中。

Springboot整个Quartz实现动态定时任务的示例代码

Springboot整个Quartz实现动态定时任务的示例代码

Springboot整个Quartz实现动态定时任务的⽰例代码简介Quartz是⼀款功能强⼤的任务调度器,可以实现较为复杂的调度功能,如每⽉⼀号执⾏、每天凌晨执⾏、每周五执⾏等等,还⽀持分布式调度。

本⽂使⽤Springboot+Mybatis+Quartz实现对定时任务的增、删、改、查、启⽤、停⽤等功能。

并把定时任务持久化到数据库以及⽀持集群。

Quartz的3个基本要素1. Scheduler:调度器。

所有的调度都是由它控制。

2. Trigger:触发器。

决定什么时候来执⾏任务。

3. JobDetail & Job: JobDetail定义的是任务数据,⽽真正的执⾏逻辑是在Job中。

使⽤JobDetail + Job⽽不是Job,这是因为任务是有可能并发执⾏,如果Scheduler直接使⽤Job,就会存在对同⼀个Job实例并发访问的问题。

⽽JobDetail & Job ⽅式,sheduler每次执⾏,都会根据JobDetail创建⼀个新的Job实例,这样就可以规避并发访问的问题。

如何使⽤Quartz1.添加依赖<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.2.3</version></dependency><dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz-jobs</artifactId><version>2.2.3</version></dependency>2.创建配置⽂件在maven项⽬的resource⽬录下创建quartz.propertiesorg.quartz.scheduler.instanceName = MySchedulerorg.quartz.scheduler.instanceId = AUTOorg.quartz.scheduler.rmi.export = falseorg.quartz.scheduler.rmi.proxy = falseorg.quartz.scheduler.wrapJobExecutionInUserTransaction = false#线程池配置org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPoolorg.quartz.threadPool.threadCount = 10org.quartz.threadPool.threadPriority = 5org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true#持久化配置org.quartz.jobStore.misfireThreshold = 50000org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX#⽀持集群org.quartz.jobStore.isClustered = trueeProperties:trueorg.quartz.jobStore.clusterCheckinInterval = 15000#使⽤weblogic连接Oracle驱动org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate#org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegateorg.quartz.jobStore.tablePrefix = QRTZ_org.quartz.jobStore.dataSource = qzDS#数据源连接信息,quartz默认使⽤c3p0数据源可以被⾃定义数据源覆盖org.quartz.dataSource.qzDS.driver = oracle.jdbc.driver.OracleDriverorg.quartz.dataSource.qzDS.URL = jdbc:oracle:thin:@localhost:1521/XEer = rootorg.quartz.dataSource.qzDS.password = 123456org.quartz.dataSource.qzDS.maxConnections = 10说明:在使⽤quartz做持久化的时候需要⽤到quartz的11张表,可以去quartz官⽹下载对应版本的quartz,解压打开docs/dbTables⾥⾯有对应数据库的建表语句。

SpringBoot定时任务Quartz使用教程

SpringBoot定时任务Quartz使用教程

SpringBoot定时任务Quartz使⽤教程Quartz是⼀个完全由java编写的开源作业调度框架,他使⽤⾮常简单。

本章主要讲解 Quartz在Spring Boot 中的使⽤。

1. 快速集成 Quartz2. 介绍 Quartz ⼏个主要技术点3. Quartz 在 Spring Boot 的配置4. Quartz 在 Spring Boot 中整合 Mybatis本着⼀篇⽂章⼀个⽰例的原则,2、3、4 将在下⼀章节说明1 新建 Spring Boot Maven ⽰例⼯程项⽬注意:是⽤来 IDEA 开发⼯具1. File > New > Project,如下图选择Spring Initializr然后点击【Next】下⼀步2. 填写GroupId(包名)、Artifact(项⽬名)即可。

点击下⼀步groupId=com.fishproartifactId=quartz3. 选择依赖Spring Web Starter前⾯打钩。

4. 项⽬名设置为spring-boot-study-quartz.2 依赖引⼊ Pom<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>3 使⽤ Quartz3.1 在启动⽂件中编写⼀个简单的使⽤QuartzApplication 中直接编写⼀启动关闭类代码@SpringBootApplicationpublic class QuartzApplication {public static void main(String[] args) {SpringApplication.run(QuartzApplication.class, args);try {// Grab the Scheduler instance from the FactoryScheduler scheduler = StdSchedulerFactory.getDefaultScheduler();//启动scheduler.start();//关闭scheduler.shutdown();} catch (SchedulerException se) {se.printStackTrace();}}}运⾏在控制台观察结果2019-08-08 15:09:01.313 INFO 21565 --- [ main] org.quartz.impl.StdSchedulerFactory : Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties' 2019-08-08 15:09:01.313 INFO 21565 --- [ main] org.quartz.impl.StdSchedulerFactory : Quartz scheduler version: 2.3.12019-08-08 15:09:01.314 INFO 21565 --- [ main] org.quartz.core.QuartzScheduler : Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.2019-08-08 15:09:01.314 INFO 21565 --- [ main] org.quartz.core.QuartzScheduler : Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutting down.2019-08-08 15:09:01.314 INFO 21565 --- [ main] org.quartz.core.QuartzScheduler : Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED paused.2019-08-08 15:09:01.314 INFO 21565 --- [ main] org.quartz.core.QuartzScheduler : Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED shutdown complete.3.2 使⽤ Job 和 Trigger1. 新建⼀个 Job 类 WelcomeJob2. 在启动类中调⽤他WelcomeJob (路径 src/main/java/com/fishpro/quartz/job/WelcomeJob.java)public class WelcomeJob implements Job {@Overridepublic void execute(JobExecutionContext arg0) throws JobExecutionException {System.out.println("这是⼀个quartz 任务");}}QuartzApplication (路径 src/main/java/com/fishpro/quartz/QuartzApplication.java)@SpringBootApplicationpublic class QuartzApplication {public static void main(String[] args) {SpringApplication.run(QuartzApplication.class, args);try {// Grab the Scheduler instance from the FactoryScheduler scheduler = StdSchedulerFactory.getDefaultScheduler();//启动scheduler.start();//新建⼀个 Job WelcomeJobJobDetail job = JobBuilder.newJob(WelcomeJob.class).withIdentity("mySimpleJob", "simpleGroup").build();// 触发器定义多长时间触发 JobDetailTrigger trigger = org.quartz.TriggerBuilder.newTrigger().withIdentity("simpleTrigger", "simpleGroup").startNow().withSchedule(simpleSchedule().withIntervalInSeconds(10).repeatForever()).build();scheduler.scheduleJob(job,trigger);//关闭//scheduler.shutdown();} catch (SchedulerException se) {se.printStackTrace();}}}运⾏结果2019-08-08 16:46:36.599 INFO 21695 --- [ main] org.quartz.impl.StdSchedulerFactory : Quartz scheduler 'DefaultQuartzScheduler' initialized from default resource file in Quartz package: 'quartz.properties' 2019-08-08 16:46:36.599 INFO 21695 --- [ main] org.quartz.impl.StdSchedulerFactory : Quartz scheduler version: 2.3.12019-08-08 16:46:36.599 INFO 21695 --- [ main] org.quartz.core.QuartzScheduler : Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.这是⼀个quartz 任务这是⼀个quartz 任务这是⼀个quartz 任务这是⼀个quartz 任务这是⼀个quartz 任务这是⼀个quartz 任务这是⼀个quartz 任务这是⼀个quartz 任务这是⼀个quartz 任务如果您觉得本系列⽰例对您有帮助,请点击右上⾓按钮 watch 以⽰⽀持谢谢参考。

springbootQuartz定时任务工具类

springbootQuartz定时任务工具类

springbootQuartz定时任务工具类package org.fh.util;import java.util.Map;import org.quartz.CronScheduleBuilder;import org.quartz.CronTrigger;import org.quartz.Job;import org.quartz.JobBuilder;import org.quartz.JobDetail;import org.quartz.JobKey;import org.quartz.Scheduler;import org.quartz.SchedulerFactory;import org.quartz.TriggerBuilder;import org.quartz.TriggerKey;import org.quartz.impl.StdSchedulerFactory;/*** 说明:定时任务管理类* 作者:FH Admin* from:*/public class QuartzManager {private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory(); //创建一个SchedulerFactory工厂实例private static String JOB_GROUP_NAME = "FH_JOBGROUP_NAME"; //任务组private static String TRIGGER_GROUP_NAME = "FH_TRIGGERGROUP_NAME"; //触发器组/**添加一个定时任务,使用默认的任务组名,触发器名,触发器组名* @param jobName 任务名* @param cls 任务* @param time 时间设置,参考quartz说明文档*/public static void addJob(String jobName, Class<? extends Job> cls, String time) {try {Scheduler sched = gSchedulerFactory.getScheduler(); //通过SchedulerFactory构建Scheduler对象JobDetail jobDetail= JobBuilder.newJob(cls).withIdentity(jobName,JOB_GROUP_NAM E).build(); //用于描叙Job实现类及其他的一些静态信息,构建一个作业实例CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger() //创建一个新的TriggerBuilder来规范一个触发器.withIdentity(jobName, TRIGGER_GROUP_NAME) //给触发器起一个名字和组名.withSchedule(CronScheduleBuilder.cronSchedule(time)).build();sched.scheduleJob(jobDetail, trigger);if (!sched.isShutdown()) {sched.start(); // 启动}} catch (Exception e) {throw new RuntimeException(e);}}/**添加一个定时任务,使用默认的任务组名,触发器名,触发器组名(带参数)* @param jobName 任务名* @param cls 任务* @param time 时间设置,参考quartz说明文档*/public static void addJob(String jobName, Class<? extends Job> cls, String time, Map<String,Object> parameter) { try {Scheduler sched = gSchedulerFactory.getScheduler(); //通过SchedulerFactory构建Scheduler对象JobDetail jobDetail= JobBuilder.newJob(cls).withIdentity(jobName,JOB_GROUP_NAM E).build(); //用于描叙Job实现类及其他的一些静态信息,构建一个作业实例jobDetail.getJobDataMap().put("parameterList", parameter); //传参数CronTrigger trigger = (CronTrigger) TriggerBuilder.newTrigger() //创建一个新的TriggerBuilder来规范一个触发器.withIdentity(jobName, TRIGGER_GROUP_NAME) //给触发器起一个名字和组名.withSchedule(CronScheduleBuilder.cronSchedule(time)).build();sched.scheduleJob(jobDetail, trigger);if (!sched.isShutdown()) {sched.start(); // 启动}} catch (Exception e) {throw new RuntimeException(e);}}/**添加一个定时任务* @param jobName 任务名* @param jobGroupName 任务组名* @param triggerName 触发器名* @param triggerGroupName 触发器组名* @param jobClass 任务* @param time 时间设置,参考quartz说明文档*/public static void addJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName, Class<? extends Job> jobClass,String time) {try {Scheduler sched = gSchedulerFactory.getScheduler();JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName,jobGroupNa me).build();// 任务名,任务组,任务执行类CronTrigger trigger = (CronTrigger) TriggerBuilder // 触发器.newTrigger().withIdentity(triggerName, triggerGroupName).withSchedule(CronScheduleBuilder.cronSchedule(time)).build();sched.scheduleJob(jobDetail, trigger);if (!sched.isShutdown()) {sched.start(); // 启动}} catch (Exception e) {throw new RuntimeException(e);}}/**添加一个定时任务(带参数)* @param jobName 任务名* @param jobGroupName 任务组名* @param triggerName 触发器名* @param triggerGroupName 触发器组名* @param jobClass 任务* @param time 时间设置,参考quartz说明文档*/public static void addJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName, Class<? extends Job> jobClass,String time, Map<String,Object> parameter) {try {Scheduler sched = gSchedulerFactory.getScheduler();JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName,jobGroupNa me).build();// 任务名,任务组,任务执行类jobDetail.getJobDataMap().put("parameterList", parameter); //传参数CronTrigger trigger = (CronTrigger) TriggerBuilder // 触发器.newTrigger().withIdentity(triggerName, triggerGroupName).withSchedule(CronScheduleBuilder.cronSchedule(time)).build();sched.scheduleJob(jobDetail, trigger);if (!sched.isShutdown()) {sched.start(); // 启动}} catch (Exception e) {throw new RuntimeException(e);}}/** 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名)* @param jobName 任务名* @param time 新的时间设置*/public static void modifyJobTime(String jobName, String time) {try {Scheduler sched = gSchedulerFactory.getScheduler(); //通过SchedulerFactory构建Scheduler对象TriggerKey triggerKey = TriggerKey.triggerKey(jobName,TRIGGER_GROUP_NAME); //通过触发器名和组名获取TriggerKeyCronTrigger trigger = (CronTrigger)sched.getTrigger(triggerKey); //通过TriggerKey获取CronTriggerif (trigger == null) {return;}String oldTime = trigger.getCronExpression();if (!oldTime.equalsIgnoreCase(time)) {JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME); //通过任务名和组名获取JobKey JobDetail jobDetail = sched.getJobDetail(jobKey);Class<? extends Job> objJobClass = jobDetail.getJobClass();removeJob(jobName);addJob(jobName, objJobClass, time);}} catch (Exception e) {throw new RuntimeException(e);}}/**修改一个任务的触发时间* @param triggerName 任务名称* @param triggerGroupName 传过来的任务名称* @param time 更新后的时间规则*/public static void modifyJobTime(String triggerName, String triggerGroupName, String time) {try {Scheduler sched = gSchedulerFactory.getScheduler(); //通过SchedulerFactory构建Scheduler对象TriggerKey triggerKey = TriggerKey.triggerKey(triggerName,triggerGroupName); //通过触发器名和组名获取TriggerKeyCronTrigger trigger = (CronTrigger)sched.getTrigger(triggerKey); //通过TriggerKey获取CronTriggerif (trigger == null) return;CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(trigger.getCronExpression());String oldTime = trigger.getCronExpression();if (!oldTime.equalsIgnoreCase(time)) {trigger = (CronTrigger)trigger.getTriggerBuilder() //重新构建trigger.withIdentity(triggerKey).withSchedule(scheduleBuilder).withSchedule(CronScheduleBuilder.cronSchedule(time)).build();sched.rescheduleJob(triggerKey, trigger); //按新的trigger 重新设置job执行}} catch (Exception e) {throw new RuntimeException(e);}}/**移除一个任务(使用默认的任务组名,触发器名,触发器组名) * @param jobName 任务名称*/public static void removeJob(String jobName) {try {Scheduler sched = gSchedulerFactory.getScheduler();TriggerKey triggerKey = TriggerKey.triggerKey(jobName,TRIGGER_GROUP_NAME); //通过触发器名和组名获取TriggerKeyJobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME); //通过任务名和组名获取JobKeysched.pauseTrigger(triggerKey); // 停止触发器sched.unscheduleJob(triggerKey);// 移除触发器sched.deleteJob(jobKey); // 删除任务} catch (Exception e) {throw new RuntimeException(e);}}/**移除一个任务* @param jobName 任务名* @param jobGroupName 任务组名* @param triggerName 触发器名* @param triggerGroupName 触发器组名*/public static void removeJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName) { try {Scheduler sched = gSchedulerFactory.getScheduler();TriggerKey triggerKey = TriggerKey.triggerKey(triggerName,triggerGroupName); //通过触发器名和组名获取TriggerKeyJobKey jobKey = JobKey.jobKey(jobName, jobGroupName); //通过任务名和组名获取JobKeysched.pauseTrigger(triggerKey); // 停止触发器sched.unscheduleJob(triggerKey);// 移除触发器sched.deleteJob(jobKey); // 删除任务} catch (Exception e) {throw new RuntimeException(e);}}/*** 启动所有定时任务*/public static void startJobs() {try {Scheduler sched = gSchedulerFactory.getScheduler(); sched.start();} catch (Exception e) {throw new RuntimeException(e);}}/*** 关闭所有定时任务*/public static void shutdownJobs() {try {Scheduler sched = gSchedulerFactory.getScheduler(); if (!sched.isShutdown()) {sched.shutdown();}} catch (Exception e) {throw new RuntimeException(e);}}}。

springboot使用quartz+XML格式处理定时任务

springboot使用quartz+XML格式处理定时任务

springboot使⽤quartz+XML格式处理定时任务 ⽹上查了许多关于springboot与quartz资料,发现使⽤XML配置的很少,简单整理了下,算是定时任务⼊门参考吧。

在pom.xml⽂件中,添加配置 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency>创建任务定时处理类 SysDataJobpackage service;import mons.logging.Log;import mons.logging.LogFactory;import org.springframework.stereotype.Service;@Servicepublic class SysDataJob {private final Log log = LogFactory.getLog(SysDataJob.class);public void deleteInfo() {("Job start");System.out.println("Job 数据处理");}}在resources⽂件下,创建quartz-config.xml<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans.xsd"><!--定时删除数据库数据任务--><!-- 配置Job类 --><bean id="sysDataJob" class="service.SysDataJob"></bean><!-- 配置JobDetail --><bean id="springQtzJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"><!-- 执⾏⽬标job --><property name="targetObject" ref="sysDataJob"></property><!-- 要执⾏的⽅法 --><property name="targetMethod" value="deleteInfo"></property><property name="concurrent" value="false"></property><!--配置为false不允许任务并发执⾏--></bean><!-- 配置tirgger触发器 --><bean id="cronTrigger1" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"><!-- jobDetail --><property name="jobDetail" ref="springQtzJob"></property><!-- cron表达式,执⾏时间每10秒执⾏⼀次 --><!-- 可以根据⾃⼰的需求指定执⾏时间 --><property name="cronExpression" value="0/10 0/1 0/1 * * ? "></property></bean><!-- 配置调度⼯⼚ --><bean id="springJobSchedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><property name="triggers"><list><ref bean="cronTrigger1"></ref><!-- <ref bean="cronTrigger2"></ref>--></list></property></bean></beans>在应⽤程序启动时,添加注解,指定xml路径 @ImportResource("classpath:quartz-config.xml")package com.howdy.quartzsimple;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ImportResource;@SpringBootApplication@ImportResource("classpath:quartz-config.xml")public class QuartzSimpleApplication {public static void main(String[] args) {SpringApplication.run(QuartzSimpleApplication.class, args);}}完整的⽬录结构,最后打印⽇志,是每10秒执⾏⼀次。

一篇文章教你使用SpringBoot如何实现定时任务

一篇文章教你使用SpringBoot如何实现定时任务

⼀篇⽂章教你使⽤SpringBoot如何实现定时任务⽬录前⾔⼀、第⼀种⽅式:@Scheduled⼆、第⼆种⽅式:Quartz总结前⾔在 Spring + SpringMVC 环境中,⼀般来说,要实现定时任务,我们有两中⽅案,⼀种是使⽤ Spring ⾃带的定时任务处理器 @Scheduled 注解,另⼀种就是使⽤第三⽅框架 Quartz ,Spring Boot 源⾃ Spring+SpringMVC ,因此天然具备这两个 Spring 中的定时任务实现策略,当然也⽀持 Quartz,本⽂我们就来看下 Spring Boot 中两种定时任务的实现⽅式。

⼀、第⼀种⽅式:@Scheduled使⽤ @Scheduled ⾮常容易,直接创建⼀个 Spring Boot 项⽬,并且添加 web 依赖 spring-boot-starter-web,项⽬创建成功后,添加 @EnableScheduling 注解,开启定时任务:@SpringBootApplication@EnableSchedulingpublic class ScheduledApplication {public static void main(String[] args) {SpringApplication.run(ScheduledApplication.class, args);}}接下来配置定时任务:@Servicepublic class HelloService {//前⾯任务的结束时间和后⾯任务的开始时间之间间隔2s@Scheduled(fixedDelay = 2000)public void fixedDelay() {System.out.println("fixedDelay>>"+new Date());}//两次定时任务开始的间隔时间为2s@Scheduled(fixedRate = 2000)public void fixedRate() {System.out.println("fixedRate>>"+new Date());}@Scheduled(initialDelay = 2000,fixedDelay = 2000)public void initialDelay() {System.out.println("initialDelay>>>"+new Date());}}(1)⾸先使⽤ @Scheduled 注解开启⼀个定时任务。

SpringBoot定时任务(schedule、quartz)

SpringBoot定时任务(schedule、quartz)

SpringBoot定时任务(schedule、quartz)Scheduled 只适合处理简单的计划任务,不能处理分布式计划任务。

优势:是spring框架提供的计划任务,开发简单,执⾏效率⽐较⾼。

且在计划任务数量太多的时候,可能出现阻塞,崩溃,延迟启动等问题。

Scheduled定时任务是spring3.0版本之后⾃带的⼀个定时任务。

其所属Spring的资源包为:spring-context-support。

所以需要使⽤Scheduled定时任务机制时,需要在⼯程中依赖对应资源,具体如下:<!-- scheduled所属资源为spring-context-support --><dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId></dependency> 如果在spring应⽤中需要启⽤Scheduled定时任务,则需要在启动类上增加注解@EnableScheduling,代表启⽤Scheduled定时任务机制。

具体如下:@SpringBootApplication@EnableSchedulingpublic class AppStarter { public static void main(String[] args) { SpringApplication.run(AppStarter.class, args); }} Scheduled定时任务的核⼼在于注解@Scheduled,这个注解的核⼼属性是cron,代表定时任务的触发计划表达式。

这个表达式的格式为:@Scheduled(cron="seconds minutes hours day month week") 或@Scheduled(cron="seconds minutes hours day month week year") 推荐使⽤第⼀种表达式形式,因为在很多其他技术中都有不同的定时任务机制,其中⽤于设置触发计划的表达式都是第⼀种cron表达式。

springboot实现定时任务的方式

springboot实现定时任务的方式

springboot实现定时任务的⽅式springboot实现定时任务的⽅式a Timer:这是java⾃带的java.util.Timer类,这个类允许你调度⼀个java.util.TimerTask任务。

使⽤这种⽅式可以让你的程序按照某⼀个频度执⾏,但不能在指定时间运⾏。

⼀般⽤的较少。

b ScheduledExecutorService:也jdk⾃带的⼀个类;是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的⼀个线程去执⾏,也就是说,任务是并发执⾏,互不影响。

c Spring Task:Spring3.0以后⾃带的task,可以将它看成⼀个轻量级的Quartz,⽽且使⽤起来⽐Quartz简单许多。

d Quartz:这是⼀个功能⽐较强⼤的的调度器,可以让你的程序在指定时间执⾏,也可以按照某⼀个频度执⾏,配置起来稍显复杂使⽤Timer以下是⼏种调度task的⽅法:1.timer.schedule(task, time);// time为Date类型:在指定时间执⾏⼀次。

2.timer.schedule(task, firstTime, period);// firstTime为Date类型,period为long// 从firstTime时刻开始,每隔period毫秒执⾏⼀次。

3.timer.schedule(task, delay)// delay 为long类型:从现在起过delay毫秒执⾏⼀次4.timer.schedule(task, delay, period)// delay为long,period为long:从现在起过delay毫秒以后,每隔period// 毫秒执⾏⼀次。

public class TestTimer {public static void main(String[] args) {TimerTask timerTask = new TimerTask() {@Overridepublic void run() {System.out.println("task run:"+ new Date());}};Timer timer = new Timer();//安排指定的任务在指定的时间开始进⾏重复的固定延迟执⾏。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

【SpringBoot】廿五、SpringBoot中使用Quartz管理定时任务2020-07-21 15:55:47定时任务在系统中用到的地方很多,例如每晚凌晨的数据备份,每小时获取第三方平台的Token 信息等等,之前我们都是在项目中规定这个定时任务什么时候启动,到时间了便会自己启动,那么我们想要停止这个定时任务的时候,就需要去改动代码,还得启停服务器,这是非常不友好的事情直至遇见 Quartz,利用图形界面可视化管理定时任务,使得我们对定时任务的管理更加方便,快捷一、Quartz 简介Quartz是一个开源的作业调度框架,它完全由Java写成,并设计用于J2SE和J2EE应用中。

它提供了巨大的灵活性而不牺牲简单性。

你能够用它来为执行一个作业而创建简单的或复杂的调度。

它有很多特征,如:数据库支持,集群,插件,EJB作业预构建,JavaMail及其它,支持cron-like表达式等等。

二、开发前戏1、引入 maven 依赖<!-- web支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Quartz 定时任务 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId></dependency>这里引入了 web 的依赖,以及 Quartz 的依赖,其余依赖请根据需求自行引入2、创建数据表数据模型:SQL语句:drop table if exists sys_quartz;/*==============================================================*//* Table: sys_quartz *//*==============================================================*/ create table sys_quartz(id bigint(20) not null auto_increment comment '主键id',class_name varchar(32) comment '任务类名',cron_expression varchar(32) comment 'cron表达式',param varchar(32) comment '参数',descript varchar(11) comment '描述',quartz_status varchar(255) comment '启动状态(0--启动1--停止)', create_time datetime comment '创建时间',create_user bigint(20) comment '创建人',status tinyint(1) default 0 comment '状态(0--正常1--停用)',del_flag tinyint(1) default 0 comment '删除状态(0,正常,1已删除)',primary key (id))type = InnoDB;alter table sys_quartz comment '定时任务信息表';三、开发进行中1、创建实体类import com.baomidou.mybatisplus.annotation.*;import com.baomidou.mybatisplus.extension.activerecord.Model;import mon.annotation.Dict;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Data;import lombok.EqualsAndHashCode;import lombok.experimental.Accessors;import java.io.Serializable;/*** <p>* 定时任务信息表* </p>** @author lizhou* @since 2020-07-21*/@Data@EqualsAndHashCode(callSuper = false)@Accessors(chain = true)@TableName("sys_quartz")@ApiModel(value="SysQuartz对象", description="定时任务信息表")public class SysQuartz extends Model<SysQuartz> {@ApiModelProperty(value = "主键id")@TableId(value = "id", type = IdType.AUTO)private Long id;@ApiModelProperty(value = "任务类名")@TableField("class_name")private String className;@ApiModelProperty(value = "cron表达式")@TableField("cron_expression")private String cronExpression;@ApiModelProperty(value = "参数")@TableField("param")private String param;@ApiModelProperty(value = "描述")@TableField("descript")private String descript;@ApiModelProperty(value = "启动状态(0--启动1--停止)")@TableField("quartz_status")private Integer quartzStatus;@ApiModelProperty(value = "状态(0--正常1--停用)")@TableField("status")private Integer status;@ApiModelProperty(value = "删除状态(0--未删除1--已删除)")@TableField("del_flag")@TableLogicprivate Integer delFlag;@ApiModelProperty(value = "创建者")@TableField("create_user")private Long createUser;@ApiModelProperty(value = "创建时间")@TableField("create_time")private String createTime;@Overrideprotected Serializable pkVal() {return this.id;}}2、实现定时任务的 CRUD下面我们就要完成定时任务的新增、修改、删除、启停等基本操作了,由于不是很复杂,这里的代码就不贴出来了,贴几张图吧四、定时任务1、定时任务类我们把定时任务都放在 job 包下面,一个定时任务就是一个文件,写一个测试的类TestJob.javaimport mon.utils.DateUtils;import lombok.extern.slf4j.Slf4j;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;/*** @ClassName TestJob* 测试定时任务* @Author Lizhou* @Date 2020-07-21 10:58:58**/@Slf4jpublic class TestJob implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {System.out.println("定时任务启动:" + DateUtils.getYmdHms());}}TestJob 这个类实现了 Job 接口,实现了 execute 方法,这里还可以接收参数这个文件在 com.zyxx.sbm.job 包下面,那么在页面新增定时任务的时候,就需要填写任务类名为:com.zyxx.sbm.job.TestJobcron 表达式的知识这里就不一一介绍了2、页面添加定时任务添加定时任务那么我们的任务类名就是:com.zyxx.sbm.job.TestJobcron 表达式:/2 * * * ?,表示两秒钟执行一次参数:我们没有传入参数3、后台添加定时任务package com.zyxx.sbm.service.impl;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage;import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import mon.shiro.SingletonLoginUtils;import mon.utils.DateUtils;import yTableResult;import mon.utils.ResponseResult;import com.zyxx.sbm.entity.SysQuartz;import com.zyxx.sbm.mapper.SysQuartzMapper;import com.zyxx.sbm.service.SysQuartzService;import lombok.extern.slf4j.Slf4j;import ng3.StringUtils;import org.quartz.*;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;/*** <p>* 定时任务信息表服务实现类* </p>** @author lizhou* @since 2020-07-21*/@Slf4j@Servicepublic class SysQuartzServiceImpl extends ServiceImpl<SysQuartzMapper, SysQuartz> implements SysQuartzService {@Autowiredprivate Scheduler scheduler;/*** 添加定时任务*/@Overridepublic ResponseResult add(SysQuartz sysQuartz) {QueryWrapper<SysQuartz> queryWrapper = new QueryWrapper<>();queryWrapper.eq("class_name", sysQuartz.getClassName());List<SysQuartz> sysQuartzList = list(queryWrapper);if (null != sysQuartzList && !sysQuartzList.isEmpty()) {return ResponseResult.getInstance().error("该任务类名已经存在");}sysQuartz.setCreateTime(DateUtils.getYmdHms());sysQuartz.setCreateUser(SingletonLoginUtils.getUserId());save(sysQuartz);// 启动if (0 == sysQuartz.getQuartzStatus()) {this.schedulerAdd(sysQuartz.getClassName().trim(), sysQuart z.getCronExpression().trim(), sysQuartz.getParam());}return ResponseResult.getInstance().success();}/*** 添加定时任务** @param className* @param cronExpression* @param param*/@Overridepublic void schedulerAdd(String className, String cronExpression, S tring param) {try {// 启动调度器scheduler.start();// 构建job信息JobDetail jobDetail = JobBuilder.newJob(getClass(className). getClass()).withIdentity(className).usingJobData("param", param).build ();// 表达式调度构建器(即任务执行的时间)CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.c ronSchedule(cronExpression);// 按新的cronExpression表达式构建一个新的triggerCronTrigger trigger = TriggerBuilder.newTrigger().withIdent ity(className).withSchedule(scheduleBuilder).build();scheduler.scheduleJob(jobDetail, trigger);} catch (SchedulerException e) {log.error(e.getMessage());} catch (RuntimeException e) {log.error(e.getMessage());} catch (Exception e) {log.error(e.getMessage());}}/*** 删除定时任务** @param className*/@Overridepublic void schedulerDelete(String className) {try {scheduler.pauseTrigger(TriggerKey.triggerKey(className));scheduler.unscheduleJob(TriggerKey.triggerKey(className));scheduler.deleteJob(JobKey.jobKey(className));} catch (Exception e) {log.error(e.getMessage(), e);}}private static Job getClass(String className) throws Exception {Class<?> class1 = Class.forName(className);return (Job) class1.newInstance();}}需要注入 Scheduler 对象,使用该对象开启或停止定时任务在启动定时任务之前,我们应先删除该任务类名开启的定时任务,防止该任务类名已经添加过了// 删除定时任务schedulerDelete(sysQuartz.getClassName().trim());// 添加定时任务schedulerAdd(sysQuartz.getClassName().trim(), sysQuartz.getCronExpressi on().trim(), sysQuartz.getParam());添加定时任务,传入任务类名,cron 表达式,参数停止定时任务,只需要:scheduler.pauseJob(JobKey.jobKey(sysQuartz.getClassName().trim()));根据任务类名,停止定时任务即可五、开发测试启动项目,在管理界面,开启定时任务,即可在控制台看到打印的信息表示我们的定时任务已经启动成功了六、优化建议当我们添加了定时任务并启动后,重新启动项目的时候,定时任务却不会自动启动,这时候,我们就需要在项目启动的时候做一些事情了,也就是系统启动任务不清楚的同学可以复习一下之前我的博客【SpringBoot】十九、SpringBoot中实现启动任务import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.zyxx.sbm.entity.SysQuartz;import com.zyxx.sbm.service.SysQuartzService;import org.springframework.beans.factory.annotation.Autowired;import mandLineRunner;import org.springframework.core.annotation.Order;import ponent;import java.util.List;/*** @ClassName SystemStartTask* 项目启动任务--启动定时任务* @Author Lizhou* @Date 2020-07-21 12:56:56**/@Component@Order(100)public class SystemQuartzStartTask implements CommandLineRunner {@Autowiredprivate SysQuartzService sysQuartzService;@Overridepublic void run(String... args) throws Exception {// 查询启动的定时任务QueryWrapper<SysQuartz> queryWrapper = new QueryWrapper<>();queryWrapper.eq("status", 0);queryWrapper.eq("quartz_status", 0);List<SysQuartz> list = sysQuartzService.list(queryWrapper);if (null != list && !list.isEmpty()) {for (SysQuartz item : list) {// 删除定时任务sysQuartzService.schedulerDelete(item.getClassName().tr im());// 添加定时任务sysQuartzService.schedulerAdd(item.getClassName().trim (), item.getCronExpression().trim(), item.getParam());}}}}从数据库查询出启动的定时任务,并将他们添加到定时任务启动中,这样项目一启动时,就会自动启动我们定义的定时任务了最后任务类名的正则表达式/^[a-zA-Z]+(\.([a-zA-Z])+)+$/cron 表达式的验证使用正则太麻烦,可以使用 Quartz 自带验证方法CronExpression.isValidExpression(cron)SpringBoot 中使用 Quartz 管理定时任务的学习就到这儿了,其实也并不难理解,相比于之前用的定时任务是不是好很多了呢,别忘了最后加上系统启动任务哦如您在阅读中发现不足,欢迎留言!!!。

相关文档
最新文档