SpringBoot2.0 dynamic integration of Quartz cron job set time

A. Introducing dependence

<!-- 引入quartz依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>

Two. Quartz configuration class

package com.example.demo.quartztask;

import org.quartz.JobDetail;
import org.quartz.spi.JobFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.quartz.CronTriggerFactoryBean; import org.springframework.scheduling.quartz.JobDetailFactoryBean; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.scheduling.quartz.SpringBeanJobFactory; import java.io.IOException; /** * @program: demo * @description: quartz动态定时任务配置类 * @author: guoxu * @create: 2019-12-31 09:43 */ @Configuration public class SchedulerConfig { @Bean public JobFactory jobFactory(ApplicationContext applicationContext) { SpringBeanJobFactory jobFactory = new SpringBeanJobFactory(); jobFactory.setApplicationContext(applicationContext); return jobFactory; } /**调度工厂bean * @param jobFactory * @throws IOException */ @Bean public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory) throws IOException { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setJobFactory(jobFactory); //QuartzScheduler 延时启动,应用启动完5秒后 QuartzScheduler 再启动 factory.setStartupDelay(5); // this allows to update triggers in DB when updating settings in config file: //用于quartz集群,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 // factory.setOverwriteExistingJobs(true); //用于quartz集群,加载quartz数据源 // factory.setDataSource(dataSource); //用于quartz集群,加载quartz数据源配置 // factory.setQuartzProperties(quartzProperties()); //注册触发器 //factory.setTriggers(cronJobTrigger); return factory; } /**加载quartz数据源配置,quartz集群时用到 * @return * @throws IOException */ // @Bean // public Properties quartzProperties() throws IOException { // PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); // propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties")); // propertiesFactoryBean.afterPropertiesSet(); // return propertiesFactoryBean.getObject(); // } /** * 创建触发器工厂 * @param jobClass * @return */ private static JobDetailFactoryBean createJobDetail(Class jobClass) { JobDetailFactoryBean factoryBean = new JobDetailFactoryBean(); factoryBean.setJobClass(jobClass); factoryBean.setDurability(true); return factoryBean; } /**创建定时器工厂 * @param jobDetail * @return */ private static CronTriggerFactoryBean createTrigger(JobDetail jobDetail) { CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean(); factoryBean.setJobDetail(jobDetail); factoryBean.setStartDelay(0L); factoryBean.setCronExpression ("0/5 * * * * ? ");//每5秒执行一次 return factoryBean; } } 

Three. MgrScheduleJob timer task entity class

Database SQL:

CREATE TABLE `t_schedule_job`  (
  `ID` char(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '任务主键', `TASK_NAME` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '任务名称', `TASK_GROUP` char(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '任务分组', `CLASS_NAME` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'class类名称地址', `DESCRIPTION` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '任务描述', `CRON_EXPRESSION` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '时间设置(定时器时间格式)', `TASK_STATUS` int(1) NULL DEFAULT NULL COMMENT '0: 执行 1: 暂停', `IS_ENABLE` int(1) NULL DEFAULT NULL COMMENT '0:启用 1:停用', `UPDATE_TIME` datetime(6) NULL DEFAULT NULL COMMENT '更新时间', `CREATE_TIME` datetime(6) NULL DEFAULT NULL COMMENT '创建时间', `CREATE_USER` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '创建人', PRIMARY KEY (`ID`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

Entity classes:

package com.example.demo.domin;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor; import org.nutz.dao.entity.annotation.*; import java.io.Serializable; import java.util.Date; /** * @Description * @Author GuoXu * @Date 2019-12-31 */ @Data @Builder @AllArgsConstructor @NoArgsConstructor @Table ( "t_schedule_job" ) public class MgrScheduleJob implements Serializable { private static final long serialVersionUID = 515061450646512139L; /** * 任务主键 */ @Name @Prev(els = @EL("uuid(32)")) @Column("ID" ) private String id; /** * 任务名称 */ @Column("TASK_NAME" ) private String taskName; /** * 任务分组 */ @Column("TASK_GROUP" ) private String taskGroup; /** * class类名称地址 */ @Column("CLASS_NAME" ) private String className; /** * 任务描述 */ @Column("DESCRIPTION") private String description; /** * 时间设置(定时器时间格式) */ @Column("CRON_EXPRESSION" ) private String cronExpression; /** * 0:执行 1:暂停 */ @Column("TASK_STATUS" ) private Integer taskStatus; /** * 0:启用 1:停用 */ @Column("IS_ENABLE") private Integer isEnable; /** * 更新时间 */ @Column("UPDATE_TIME" ) private Date updateTime; /** * 创建时间 */ @Column("CREATE_TIME" ) private Date createTime; /** * 创建人 */ @Column("CREATE_USER" ) private String createUser; } 

Four. Quartz regular tasks for class

This is in order to better distinguish the business logic, so timing of the task is divided into classes based approach, the timing and control tasks implemented method of class

The following IBaseService and BaseService class, is a repackaging curd method nutzDao based, want to learn more about can see my other article

interface:

package com.example.demo.quartztask;

import com.example.demo.base.IBaseService;
import com.example.demo.domin.MgrScheduleJob;
import org.quartz.SchedulerException;

import java.util.List; /** * @program: demo * @description: quartz定时任务Service * @author: guoxu * @create: 2019-12-31 10:21 */ public interface IJobAndTriggerService extends IBaseService<MgrScheduleJob> { /** * 新增任务 * @param scheduleJob * @throws Exception */ void addOrUpdateJob(MgrScheduleJob scheduleJob) throws Exception; /** * Scheduler 删除定时任务 * @param scheduleJob * @throws Exception */ void stopJob(MgrScheduleJob scheduleJob) throws SchedulerException; /** * Scheduler 暂停定时任务 * @param scheduleJob * @throws Exception */ void pauseJob(MgrScheduleJob scheduleJob) throws SchedulerException; /** * Scheduler 恢复定时任务 * @param scheduleJob * @throws Exception */ void resumejob(MgrScheduleJob scheduleJob) throws SchedulerException; /** * 立即执行一个job * @param scheduleJob * @throws SchedulerException */ void runAJobNow(MgrScheduleJob scheduleJob) throws SchedulerException; /** * 获取所有计划中的任务列表 * @return * @throws SchedulerException */ List<MgrScheduleJob> getAllJob() throws SchedulerException; /** * 获取所有执行中的任务列表 * @return * @throws SchedulerException */ List<MgrScheduleJob> getRunningJob() throws SchedulerException; /** * 暂停所有任务 * @throws SchedulerException */ void pauseAllJobs() throws SchedulerException; /** * 恢复所有任务 * @throws SchedulerException */ void resumeAllJobs() throws SchedulerException; } 

achieve:

package com.example.demo.quartztask;

import com.example.demo.base.BaseServiceImpl;
import com.example.demo.domin.MgrScheduleJob;
import lombok.extern.slf4j.Slf4j;
import org.nutz.dao.Cnd; import org.quartz.*; import org.quartz.impl.matchers.GroupMatcher; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.stereotype.Service; import org.springframework.util.Assert; import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.List; import java.util.Set; /** * @program: demo * @description: quartz定时任务实现类 * @author: guoxu * @create: 2019-12-31 10:45 */ /** * Scheduler:调度器,进行任务调度;quartz的大脑 * Job:业务job,亦可称业务组件;定时任务的具体执行业务需要实现此接口,调度器会调用此接口的execute方法完成我们的定时业务 * JobDetail:用来定义业务Job的实例,我们可以称之为quartz job,很多时候我们谈到的job指的是JobDetail * Trigger:触发器,用来定义一个指定的Job何时被执行 * JobBuilder:Job构建器,用来定义或创建JobDetail的实例;JobDetail限定了只能是Job的实例 * TriggerBuilder:触发器构建器,用来定义或创建触发器的实例 */ @Slf4j @Service public class JobAndTriggerServiceImpl extends BaseServiceImpl<MgrScheduleJob> implements IJobAndTriggerService{ @Autowired private SchedulerFactoryBean schedulerFactoryBean; /** * 被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。 * @throws Exception */ @PostConstruct public void init() { // 这里获取任务信息数据 List<MgrScheduleJob> jobList = nutzDao.query(MgrScheduleJob.class, Cnd.where("isEnable", "=", 0)); jobList.forEach(job -> { try { if (job.getTaskStatus() == 1){ job.setTaskStatus(0); nutzDao.update(job); } addOrUpdateJob(job); } catch (Exception e) { e.printStackTrace(); log.error("初始化定时任务列表异常->{}",e.getMessage()); } }); } @Override public void addOrUpdateJob(MgrScheduleJob mgrScheduleJob) throws Exception { //获去调度器实例 Scheduler scheduler = schedulerFactoryBean.getScheduler(); TriggerKey triggerKey = TriggerKey.triggerKey(mgrScheduleJob.getTaskName(), mgrScheduleJob.getTaskGroup()); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); //trigger不存在,创建一个 if (null == trigger) { //新增定时任务 Class clazz = Class.forName(mgrScheduleJob.getClassName()); //判断clazz是否为null,是则抛出异常 Assert.notNull(clazz, "定时任务执行类为NULL"); //初始化一个类,生成一个实例 clazz.newInstance(); // 构建job信息 JobDetail jobDetail = JobBuilder.newJob(clazz) .withIdentity(mgrScheduleJob.getTaskName(),mgrScheduleJob.getTaskGroup()).build(); // 表达式调度构建器(即任务执行的时间) CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(mgrScheduleJob.getCronExpression()); // 按新的cronExpression表达式构建一个新的trigger trigger = TriggerBuilder.newTrigger().withIdentity(mgrScheduleJob.getTaskName(),mgrScheduleJob.getTaskGroup()) .withSchedule(scheduleBuilder).build(); //设置job执行 scheduler.scheduleJob(jobDetail, trigger); } else { // Trigger已存在,那么更新相应的定时设置 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(mgrScheduleJob.getCronExpression()); // 按新的cronExpression表达式重新构建trigger trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); // 按新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey, trigger); } } @Override public void stopJob(MgrScheduleJob scheduleJob) throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getTaskName(), scheduleJob.getTaskGroup()); scheduler.deleteJob(jobKey); } @Override public void pauseJob(MgrScheduleJob scheduleJob) throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getTaskName(), scheduleJob.getTaskGroup()); scheduler.pauseJob(jobKey); } @Override public void resumejob(MgrScheduleJob scheduleJob) throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getTaskName(), scheduleJob.getTaskGroup()); scheduler.resumeJob(jobKey); } @Override public void runAJobNow(MgrScheduleJob scheduleJob) throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); JobKey jobKey = JobKey.jobKey(scheduleJob.getTaskName(), scheduleJob.getTaskGroup()); scheduler.triggerJob(jobKey); } @Override public List<MgrScheduleJob> getAllJob() throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); List<MgrScheduleJob> jobList = new ArrayList<MgrScheduleJob>(); GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup(); Set<JobKey> jobKeys = scheduler.getJobKeys(matcher); jobKeys.forEach(jobKey -> { List<? extends Trigger> triggers = null; try { triggers = scheduler.getTriggersOfJob(jobKey); } catch (SchedulerException e) { e.printStackTrace(); } if (triggers != null) { triggers.forEach(trigger -> { MgrScheduleJob job = new MgrScheduleJob(); job.setTaskName(jobKey.getName()); job.setTaskGroup(jobKey.getGroup()); if (trigger instanceof CronTrigger) { CronTrigger cronTrigger = (CronTrigger) trigger; String cronExpression = cronTrigger.getCronExpression(); job.setCronExpression(cronExpression); } jobList.add(job); }); } }); return jobList; } @Override public List<MgrScheduleJob> getRunningJob() throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs(); List<MgrScheduleJob> jobList = new ArrayList<MgrScheduleJob>(executingJobs.size()); for (JobExecutionContext executingJob : executingJobs) { MgrScheduleJob job = new MgrScheduleJob(); JobDetail jobDetail = executingJob.getJobDetail(); JobKey jobKey = jobDetail.getKey(); job.setTaskName(jobKey.getName()); job.setTaskGroup(jobKey.getGroup()); Trigger trigger = executingJob.getTrigger(); // Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey()); if (trigger instanceof CronTrigger) { CronTrigger cronTrigger = (CronTrigger) trigger; String cronExpression = cronTrigger.getCronExpression(); job.setCronExpression(cronExpression); } jobList.add(job); } return jobList; } @Override public void pauseAllJobs() throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); scheduler.pauseAll(); } @Override public void resumeAllJobs() throws SchedulerException { Scheduler scheduler = schedulerFactoryBean.getScheduler(); scheduler.resumeAll(); } } 

Five. MgrScheduleJob timed Mission Control Service category

interface:

package com.example.demo.quartztask;

import com.example.demo.base.IBaseService;
import com.example.demo.domin.MgrScheduleJob;

/**
 * @program: demo * @description: 定时任务实体Service类 * @author: guoxu * @create: 2019-12-31 14:48 */ public interface IScheduleJobService extends IBaseService<MgrScheduleJob> { /** * 添加或新增定时任务 * @param mgrScheduleJob * @throws Exception */ void addOrUpdateScheduleJob(MgrScheduleJob mgrScheduleJob) throws Exception; /** * 修改定时任务启用状态 0 启用 1 停用 * @param id * @throws Exception */ void isEnableScheduleJob(String id) throws Exception; /** * 暂停/恢复 定时任务 * @param id * @throws Exception */ void pauseScheduleJob(String id) throws Exception; /** * 删除定时任务 * @param id * @throws Exception */ void deleteScheduleJob(String id) throws Exception; /** * 立即运行定时任务 * @param id * @throws Exception */ void runScheduleJob(String id) throws Exception; } 

achieve:

package com.example.demo.quartztask;

import com.example.demo.base.BaseServiceImpl;
import com.example.demo.domin.MgrScheduleJob;
import com.example.demo.utils.StringUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Date; /** * @program: demo * @description: 定时任务Service实现类 * @author: guoxu * @create: 2019-12-31 15:17 */ @Service public class ScheduleJobServiceImpl extends BaseServiceImpl<MgrScheduleJob> implements IScheduleJobService { @Autowired private IJobAndTriggerService jobAndTriggerService; @Override public void addOrUpdateScheduleJob(MgrScheduleJob mgrScheduleJob) throws Exception { if (StringUtil.isNotEmpty(mgrScheduleJob.getId())){ //更新任务 mgrScheduleJob.setTaskStatus(0); mgrScheduleJob.setIsEnable(0); mgrScheduleJob.setUpdateTime(new Date()); update(mgrScheduleJob); }else { //新增任务 mgrScheduleJob.setTaskStatus(0); mgrScheduleJob.setIsEnable(0); mgrScheduleJob.setCreateTime(new Date()); mgrScheduleJob.setUpdateTime(new Date()); add(mgrScheduleJob); } jobAndTriggerService.addOrUpdateJob(mgrScheduleJob); } @Override public void isEnableScheduleJob(String id) throws Exception { MgrScheduleJob mgrScheduleJob = load(id); if (mgrScheduleJob.getIsEnable() == 0){ //停用任务 mgrScheduleJob.setIsEnable(1); update(mgrScheduleJob); jobAndTriggerService.stopJob(mgrScheduleJob); }else if (mgrScheduleJob.getIsEnable() == 1){ //启用任务 mgrScheduleJob.setIsEnable(0); update(mgrScheduleJob); jobAndTriggerService.addOrUpdateJob(mgrScheduleJob); } } @Override public void pauseScheduleJob(String id) throws Exception { MgrScheduleJob mgrScheduleJob = load(id); if (mgrScheduleJob.getTaskStatus() == 0){ //暂停任务 mgrScheduleJob.setTaskStatus(1); update(mgrScheduleJob); jobAndTriggerService.pauseJob(mgrScheduleJob); }else if (mgrScheduleJob.getTaskStatus() == 1){ //执行任务 mgrScheduleJob.setTaskStatus(0); update(mgrScheduleJob); jobAndTriggerService.resumejob(mgrScheduleJob); } } @Override public void deleteScheduleJob(String id) throws Exception { MgrScheduleJob mgrScheduleJob = load(id); jobAndTriggerService.stopJob(mgrScheduleJob); deleteById(id); } @Override public void runScheduleJob(String id) throws Exception { jobAndTriggerService.runAJobNow(load(id)); } } 

VI. Timing mission control interface calls ScheduleJobController

package com.example.demo.quartztask;

import com.example.demo.domin.MgrScheduleJob;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** * @program: demo * @description: 定时任务Controller * @author: guoxu * @create: 2019-12-31 16:53 */ @Api(tags = "定时任务管理模块",description = "ScheduleJobController") @Slf4j @RestController @RequestMapping("sys/schedule") public class ScheduleJobController { @Autowired private IScheduleJobService scheduleJobService; @ApiOperation("添加或更新定时任务") @PostMapping("add") public String addOrUpdate(@RequestBody MgrScheduleJob mgrScheduleJob){ try { scheduleJobService.addOrUpdateScheduleJob(mgrScheduleJob); return "定时任务添加或更新成功"; } catch (Exception e) { log.error("定时任务新增或更新失败==>【{}】",e.getMessage()); return "定时任务添加或更新失败"; } } @ApiOperation("删除定时任务") @PostMapping("delete") public String delete(@ApiParam(value = "",required = true) @RequestParam String id){ try { scheduleJobService.deleteScheduleJob(id); return "删除定时任务成功"; } catch (Exception e) { log.error("删除定时任务失败==>【{}】",e.getMessage()); return "删除定时任务失败"; } } @ApiOperation("启用或停用定时任务") @PostMapping("isEnable") public String isEnable(@ApiParam(value = "",required = true) @RequestParam String id){ try { scheduleJobService.isEnableScheduleJob(id); return "启用或停用定时任务成功"; } catch (Exception e) { log.error("启用或停用定时任务失败==>【{}】",e.getMessage()); return "启用或停用定时任务失败"; } } @ApiOperation("暂停或执行定时任务") @PostMapping("pauseJob") public String pauseJob(@ApiParam(value = "",required = true) @RequestParam String id){ try { scheduleJobService.pauseScheduleJob(id); return "暂停或执行定时任务成功"; } catch (Exception e) { log.error("暂停或执行定时任务失败==>【{}】",e.getMessage()); return "暂停或执行定时任务失败"; } } } 

VII. Creating a scheduled task execution classes

Custom timing task execution classes must inherit QuartzJobBean:

package com.example.demo.quartztask.job;

import com.example.demo.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException; import org.springframework.scheduling.quartz.QuartzJobBean; /** * @program: demo * @description: 测试定时任务类 * @author: guoxu * @create: 2019-12-31 10:13 * * QuartzJobBean implements Job */ @Slf4j public class TestSchedulerJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { log.info("执行测试定时任务==>【{}】", DateUtil.getTodayTimeString()); } } 

New regular tasks SQL example:

-- ----------------------------
-- Records of t_schedule_job
-- ----------------------------
INSERT INTO `t_schedule_job` VALUES ('rl857upqqsgdio86kpdnmuf95b', '测试任务', 'test', 'com.example.demo.quartztask.job.TestSchedulerJob', '测试创建的定时任务', '0/5 * * * * ?', 0, 1, '2019-12-31 18:50:26.674000', '2019-12-31 18:50:26.674000', 'admin');

 Source: webmaster platform

Guess you like

Origin www.cnblogs.com/1994july/p/12163935.html