SpringBoot整合Quartz定时任务管理
- pom.xml
<!-- quartz --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
- 添加配置类
@Configuration public class SchedulerConfig implements SchedulerFactoryBeanCustomizer { @Override public void customize(SchedulerFactoryBean schedulerFactoryBean) { schedulerFactoryBean.setStartupDelay(2); schedulerFactoryBean.setAutoStartup(true); schedulerFactoryBean.setOverwriteExistingJobs(true); } }
- application.yml 配置
项目使用的是 Druid
#Quartz相关属性配置
quartz:
#相关属性配置
properties:
org:
quartz:
scheduler:
instanceName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 10000
useProperties: true
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 10
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
#数据库方式
job-store-type: jdbc
- service
public class JobAndTriggerVo implements Serializable { private static final long serialVersionUID = 1L; // 类名 private String jobName; // 描述 private String jobDescription; // 组 private String jobGroupName; // 类名 private String jobClassName; // 触发类 private String triggerName; // 触发组 private String triggerGroupName; // 上次执行时间 private String prevFireTime; // 下次执行时间 private String nextFireTime; // 时间表达式 private String cronExpression; // 状态 private String triggerState; }
public interface JobAndTriggerService { /** * 查询定时任务分页 * @param map * @return */ public PageUtils<JobAndTriggerVo> listJobAndTriggerDetails(Map<String, Object> map); /** * 查询定时任务 * @return */ public PublicBean getJobAndTriggerVo(); /** * 添加任务 * @param jobClassName * @param jobGroupName * @param cronExpression * @return * @throws Exception */ public PublicBean addJob(String jobClassName, String jobGroupName, String cronExpression); /** * 更新定时任务 * @param jobClassName * @param jobGroupName * @param cronExpression * @return * @throws Exception */ public PublicBean updateJob(String jobClassName, String jobGroupName, String cronExpression); /** * 删除定时任务 * @param jobClassName * @param jobGroupName * @return * @throws Exception */ public PublicBean deleteJob(String jobClassName, String jobGroupName); /** * 暂停定时任务 * @param jobClassName * @param jobGroupName * @return * @throws Exception */ public PublicBean pauseJob(String jobClassName, String jobGroupName); /** * 恢复任务 * @param jobClassName * @param jobGroupName * @return * @throws Exception */ public PublicBean resumeJob(String jobClassName, String jobGroupName); }
@Service public class JobAndTriggerServiceImpl implements JobAndTriggerService{ @Autowired private Scheduler scheduler; @Autowired JobAndTriggerMapper jobAndTriggerMapper; private static final Logger log = LoggerFactory.getLogger(JobAndTriggerServiceImpl.class); /** * 查询定时任务分页 * @param map * @return */ @Override public PageUtils<JobAndTriggerVo> listJobAndTriggerDetails(Map<String, Object> map) { PageUtils<JobAndTriggerVo> pageUtils = new PageUtils<>(); try { PageParameter pageParameter = new PageParameter(map); List<JobAndTriggerVo> jobList = jobAndTriggerMapper.listJobAndTriggerDetails(pageParameter); Integer total = jobAndTriggerMapper.countJobAndTriggerDetails(pageParameter); pageUtils.setRows(jobList); pageUtils.setTotal(total); } catch (Exception e) { e.printStackTrace(); log.error("查询定时任务分页失败" + e.getMessage()); } return pageUtils; } /** * 查询定时任务 * @return */ @Override public PublicBean getJobAndTriggerVo() { PublicBean publicBean = new PublicBean(); try { JobAndTriggerVo jobAndTriggerVo = jobAndTriggerMapper.getJobAndTriggerVo(); publicBean.setStatus(StatusCode.SUCCESS).setData(jobAndTriggerVo); } catch (Exception e) { e.printStackTrace(); log.error("获取定时任务失败" + e.getMessage()); publicBean.setStatus(StatusCode.FAIL).setData("获取定时任务异常"); } return publicBean; } /** * 添加任务 * @param jobClassName * @param jobGroupName * @param cronExpression * @return * @throws Exception */ @Override public PublicBean addJob(String jobClassName, String jobGroupName, String cronExpression) { PublicBean publicBean = new PublicBean(); try { // 启动调度器 scheduler.start(); // 构建job信息 JobDetail jobDetail = JobBuilder.newJob(getClass(jobClassName).getClass()).withIdentity(jobClassName, jobGroupName).build(); // 表达式调度构建器(即任务执行的时间) CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression); // 按新的cronExpression表达式构建一个新的trigger CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobClassName, jobGroupName).withSchedule(scheduleBuilder).build(); try { scheduler.scheduleJob(jobDetail, trigger); publicBean.setStatus(StatusCode.SUCCESS).setData("创建定时任务成功"); } catch (SchedulerException e) { publicBean.setStatus(StatusCode.FAIL).setData("创建定时任务异常"); } } catch (Exception e) { e.printStackTrace(); log.error("失败" + e.getMessage()); publicBean.setStatus(StatusCode.FAIL).setData("创建定时任务异常"); } return publicBean; } /** * 更新定时任务 * @param jobClassName * @param jobGroupName * @param cronExpression * @return * @throws Exception */ @Override public PublicBean updateJob(String jobClassName, String jobGroupName, String cronExpression) { PublicBean publicBean = new PublicBean(); try { TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobGroupName); // 表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); // 按新的cronExpression表达式重新构建trigger trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); // 按新的trigger重新设置job执行 scheduler.rescheduleJob(triggerKey, trigger); publicBean.setStatus(StatusCode.SUCCESS).setData("修改定时任务成功"); } catch (Exception e) { e.printStackTrace(); log.error("失败" + e.getMessage()); publicBean.setStatus(StatusCode.FAIL).setData("修改定时任务异常"); } return publicBean; } /** * 删除定时任务 * @param jobClassName * @param jobGroupName * @return * @throws Exception */ @Override public PublicBean deleteJob(String jobClassName, String jobGroupName) { PublicBean publicBean = new PublicBean(); try { scheduler.pauseTrigger(TriggerKey.triggerKey(jobClassName, jobGroupName)); scheduler.unscheduleJob(TriggerKey.triggerKey(jobClassName, jobGroupName)); scheduler.deleteJob(JobKey.jobKey(jobClassName, jobGroupName)); publicBean.setStatus(StatusCode.SUCCESS).setData("删除定时任务成功"); } catch (Exception e) { e.printStackTrace(); log.error("失败" + e.getMessage()); publicBean.setStatus(StatusCode.FAIL).setData("删除定时任务异常"); } return publicBean; } /** * 暂停定时任务 * @param jobClassName * @param jobGroupName * @return * @throws Exception */ @Override public PublicBean pauseJob(String jobClassName, String jobGroupName) { PublicBean publicBean = new PublicBean(); try { scheduler.pauseJob(JobKey.jobKey(jobClassName, jobGroupName)); publicBean.setStatus(StatusCode.SUCCESS).setData("暂停定时任务成功"); } catch (Exception e) { e.printStackTrace(); log.error("失败" + e.getMessage()); publicBean.setStatus(StatusCode.FAIL).setData("暂停定时任务异常"); } return publicBean; } /** * 恢复任务 * @param jobClassName * @param jobGroupName * @return * @throws Exception */ @Override public PublicBean resumeJob(String jobClassName, String jobGroupName) { PublicBean publicBean = new PublicBean(); try { scheduler.resumeJob(JobKey.jobKey(jobClassName, jobGroupName)); publicBean.setStatus(StatusCode.SUCCESS).setData("恢复定时任务成功"); } catch (Exception e) { e.printStackTrace(); log.error("失败" + e.getMessage()); publicBean.setStatus(StatusCode.FAIL).setData("恢复定时任务异常"); } return publicBean; } /** * * @param classname * @return * @throws Exception */ public static BaseJob getClass(String classname) throws Exception { Class<?> class1 = Class.forName(classname); return (BaseJob) class1.newInstance(); } }
- job
public interface BaseJob extends Job{ public void execute(JobExecutionContext context) throws JobExecutionException; }
public class OneJob implements BaseJob{ private static final Logger log = LoggerFactory.getLogger(OneJob.class); public OneJob() { System.out.println(new Date() + "OneJob 任务开始------------------------------------"); try { Thread.sleep(10000); System.out.println("任务 OneJob 开始干活。。。"); } catch (InterruptedException e) { e.printStackTrace(); log.error("OneJob 定时任务报错:" + e.getMessage()); } System.out.println(new Date() + "OneJob 任务结束------------------------------------"); } @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("OneJob执行时间: " + new Date()); } }
- mapper
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.juli.mapper.JobAndTriggerMapper"> <!-- 分页查询定时任务 --> <select id="listJobAndTriggerDetails" resultType="com.juli.userauthority.vo.JobAndTriggerVo"> SELECT jd.JOB_NAME AS jobName, jd.DESCRIPTION AS jobDescription, jd.JOB_GROUP AS jobGroupName, jd.JOB_CLASS_NAME AS jobClassName, t.TRIGGER_NAME AS triggerName, t.TRIGGER_GROUP AS triggerGroupName, FROM_UNIXTIME(t.PREV_FIRE_TIME/1000,'%Y-%m-%d %T') AS prevFireTime, FROM_UNIXTIME(t.NEXT_FIRE_TIME/1000,'%Y-%m-%d %T') AS nextFireTime, ct.CRON_EXPRESSION AS cronExpression, t.TRIGGER_STATE AS triggerState FROM QRTZ_JOB_DETAILS jd JOIN QRTZ_TRIGGERS t JOIN QRTZ_CRON_TRIGGERS ct ON jd.JOB_NAME = t.JOB_NAME AND t.TRIGGER_NAME = ct.TRIGGER_NAME AND t.TRIGGER_GROUP = ct.TRIGGER_GROUP <if test="offset != null and limit != null"> limit #{offset}, #{limit} </if> </select> </mapper>
- 注意事项
*数据库表名大小写问题
- 最终效果
参考:https://blog.csdn.net/lx1309244704/article/details/81810373