本文是借鉴springboot整合Quartz实现动态配置定时任务_牛奋lch-CSDN博客_springboot定时任务动态配置
编写。
业务需求场景:定时任务执行时间经常需要变动
实现逻辑:
1、创建一个定时任务(ScheduledTask)
package com.gaozhen.webservicedemo.service;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
/**
* 路径:com.example.demo.service
* 类名:
* 功能:任务类
* 备注:
* 创建人:typ
* 创建时间:2018/10/10 12:03
* 修改人:
* 修改备注:
* 修改时间:
*/
@Configuration
@Component
@EnableScheduling
public class ScheduledTask {
public void sayHello(){
System.out.println("执行此定时任务方法");
}
}
2、创建QuartzConfig配置类,初始化定时任务执行方式
jobDetail初始化定时任务
jobTrigger初始化cron表达式
scheduler启动定时任务
package com.gaozhen.webservicedemo.config;
import com.gaozhen.webservicedemo.service.ScheduledTask;
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;
import java.util.Date;
/**
* 路径:com.example.demo.config
* 类名:
* 功能:Quartz配置类
* 备注:
* 创建人:typ
* 创建时间:2018/10/10 12:05
* 修改人:
* 修改备注:
* 修改时间:
*/
@Configuration
public class QuartzConfig {
/**
* 方法名:
* 功能:配置定时任务
* 描述:
* 创建人:typ
* 创建时间:2018/10/10 12:06
* 修改人:
* 修改描述:
* 修改时间:
*/
@Bean(name = "jobDetail")
public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduledTask task){
MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
/*
* 是否并发执行
* 例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了,
* 如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行
*/
jobDetail.setConcurrent(false);
//设置定时任务的名字
jobDetail.setName("srd-demo");
//设置任务的分组,这些属性都可以在数据库中,在多任务的时候使用
jobDetail.setGroup("srd");
//为需要执行的实体类对应的对象
jobDetail.setTargetObject(task);
/*
* sayHello为需要执行的方法
* 通过这几个配置,告诉JobDetailFactoryBean我们需要执行定时执行ScheduleTask类中的sayHello方法
*/
jobDetail.setTargetMethod("sayHello");
System.out.println("jobDetail 初始化成功!");
return jobDetail;
}
/**
* 方法名:
* 功能:配置定时任务的触发器,也就是什么时候触发执行定时任务
* 描述:
* 创建人:typ
* 创建时间:2018/10/10 12:14
* 修改人:
* 修改描述:
* 修改时间:
*/
@Bean(name = "jobTrigger")
public CronTriggerFactoryBean cronTriggerFactoryBean(MethodInvokingJobDetailFactoryBean jobDetail){
CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
trigger.setJobDetail(jobDetail.getObject());
// trigger.setStartTime(new Date());
//初始化的cron表达式(每天上午10:15触发)
trigger.setCronExpression("00 31 14 01 11 ?");
trigger.setCronExpression("0 30 20 * * ?");// 初始时的cron表达式
//trigger的name
trigger.setName("srd-demo");
System.out.println("jobTrigger 初始化成功!");
return trigger;
}
/**
* 方法名:
* 功能:定义quartz调度工厂
* 描述:
* 创建人:typ
* 创建时间:2018/10/10 14:06
* 修改人:
* 修改描述:
* 修改时间:
*/
@Bean(name = "scheduler")
public SchedulerFactoryBean schedulerFactoryBean(Trigger trigger){
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
//用于quartz集群,QuartzScheduler启动时更新已存在的job
factoryBean.setOverwriteExistingJobs(true);
//延时启动,应用启动1秒后
factoryBean.setStartupDelay(1);
//注册触发器
factoryBean.setTriggers(trigger);
System.out.println("scheduler 初始化成功!");
return factoryBean;
}
}
3、根据初始化注册的信息找到当前定时任务更新cron表达式,并重新执行
package com.gaozhen.webservicedemo.controller;
import com.gaozhen.webservicedemo.config.TestRun;
import com.gaozhen.webservicedemo.service.UserService;
import com.gaozhen.webservicedemo.util.CronUtil;
import com.gaozhen.webservicedemo.vo.User;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@RestController
public class TestController {
@Resource(name = "jobDetail")
private JobDetail jobDetail;
@Resource(name = "jobTrigger")
private CronTrigger cronTrigger;
@Resource(name = "scheduler")
private Scheduler scheduler;
@GetMapping("/cron")
public String cron(String time) throws SchedulerException {
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date =null;
try {
date = simpleDateFormat.parse(time);
} catch (ParseException e) {
e.printStackTrace();
}
String searchCron=CronUtil.getCron(date);
System.out.println(searchCron);
//表达式调度构建器
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(searchCron);
//按新的cronExpression表达式重新构建trigger
trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey());
trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey()).withSchedule(scheduleBuilder).build();
// 按新的trigger重新设置job执行
scheduler.rescheduleJob(cronTrigger.getKey(), trigger);
return "ok";
}
}