SpringBoot 集成 Quartz + MySQL

打印 上一主题 下一主题

主题 878|帖子 878|积分 2634

Quartz 简单使用
Java SpringBoot 中,动态执行 bean 对象中的方法
源代码地址 => https://gitee.com/VipSoft/VipBoot/tree/develop/vipsoft-quartz
工作原理解读

只要配置好 DataSource Quartz 会自动进行表的数据操作,
添加 Quartz Job 任务

保存 QRTZ_JOB_DETAILS、QRTZ_TRIGGERS =>  QRTZ_CRON_TRIGGERS
  1. public void addJob(QuartzJob job) throws SchedulerException {
  2.   ....
  3.   JobDetail jobDetail = JobBuilder.newJob(jobClass)
  4.                     .withIdentity(jobKey)
  5.                     .build();
  6.   // 放入参数,运行时的方法可以获取
  7.   jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job);
  8.   //该行代码执行后,会将定时任务插入 QRTZ_JOB_DETAILS 等相关表
  9.   scheduler.scheduleJob(jobDetail, trigger);
  10.   ....
  11. }
复制代码
  1. //org.quartz.impl.jdbcjobstore.JobStoreSupport
  2. public void storeJobAndTrigger(final JobDetail newJob, final OperableTrigger newTrigger) throws JobPersistenceException {
  3.     this.executeInLock(this.isLockOnInsert() ? "TRIGGER_ACCESS" : null, new JobStoreSupport.VoidTransactionCallback() {
  4.         public void executeVoid(Connection conn) throws JobPersistenceException {
  5.             JobStoreSupport.this.storeJob(conn, newJob, false);  //数据保存 QRTZ_JOB_DETAILS 表
  6.             JobStoreSupport.this.storeTrigger(conn, newTrigger, newJob, false, "WAITING", false, false); //数据保存 QRTZ_TRIGGERS 表
  7.         }
  8.     });
  9. }
  10. public int insertTrigger(...){
  11. INSERT_TRIGGER
  12. insertExtendedTriggerProperties => INSERT_CRON_TRIGGER OR INSERT_BLOB_TRIGGER
  13. }
复制代码
详见:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
将 job.getJobDataMap(),对像序列化后,存入 JOB_DETAILS.JOB_DATA字段,可以是一个对像,以执行定时任务时,会把该字段反序列化,根据前期设定的内容进行业务处理

获取 Quartz Job 任务

执行计划任务时,获取 Job Detail
  1. QuartzSchedulerThread.run()
  2. => qsRsrcs.getJobStore().acquireNextTriggers()
  3. => txCallback.execute(conn)
  4. => JobStoreSupport.acquireNextTriggers()
  5. => JobStoreSupport.retrieveJob()
  6. => StdJDBCDelegate.selectJobDetail()
复制代码

删除 Quartz Job 任务
  1. /**
  2. * <p>
  3. * Delete the base trigger data for a trigger.
  4. * </p>
  5. *
  6. * @param conn
  7. *          the DB Connection
  8. * @return the number of rows deleted
  9. */
  10. public int deleteTrigger(Connection conn, TriggerKey triggerKey) throws SQLException {
  11.     PreparedStatement ps = null;
  12.     deleteTriggerExtension(conn, triggerKey);
  13.    
  14.     try {
  15.         ps = conn.prepareStatement(rtp(DELETE_TRIGGER));
  16.         ps.setString(1, triggerKey.getName());
  17.         ps.setString(2, triggerKey.getGroup());
  18.         return ps.executeUpdate();
  19.     } finally {
  20.         closeStatement(ps);
  21.     }
  22. }
复制代码
清除数据
  1. /**
  2. * 清任务顺序
  3. */
  4. public void clearData(Connection conn)
  5.     throws SQLException {
  6.     PreparedStatement ps = null;
  7.     try {
  8.         ps = conn.prepareStatement(rtp(DELETE_ALL_SIMPLE_TRIGGERS));
  9.         ps.executeUpdate();
  10.         ps.close();
  11.         ps = conn.prepareStatement(rtp(DELETE_ALL_SIMPROP_TRIGGERS));
  12.         ps.executeUpdate();
  13.         ps.close();
  14.         ps = conn.prepareStatement(rtp(DELETE_ALL_CRON_TRIGGERS));
  15.         ps.executeUpdate();
  16.         ps.close();
  17.         ps = conn.prepareStatement(rtp(DELETE_ALL_BLOB_TRIGGERS));
  18.         ps.executeUpdate();
  19.         ps.close();
  20.         ps = conn.prepareStatement(rtp(DELETE_ALL_TRIGGERS));
  21.         ps.executeUpdate();
  22.         ps.close();
  23.         ps = conn.prepareStatement(rtp(DELETE_ALL_JOB_DETAILS));
  24.         ps.executeUpdate();
  25.         ps.close();
  26.         ps = conn.prepareStatement(rtp(DELETE_ALL_CALENDARS));
  27.         ps.executeUpdate();
  28.         ps.close();
  29.         ps = conn.prepareStatement(rtp(DELETE_ALL_PAUSED_TRIGGER_GRPS));
  30.         ps.executeUpdate();
  31.     } finally {
  32.         closeStatement(ps);
  33.     }
  34. }
复制代码
Demo 代码

MySQL 脚本

https://github.com/quartz-scheduler/quartz/blob/v2.3.2/quartz-core/src/main/resources/org/quartz/impl/jdbcjobstore/tables_mysql.sql
清除数据
  1. DELETE FROM qrtz_simple_triggers ;
  2. DELETE FROM qrtz_simprop_triggers ;
  3. DELETE FROM qrtz_cron_triggers ;
  4. DELETE FROM qrtz_blob_triggers ;
  5. DELETE FROM qrtz_triggers ;
  6. DELETE FROM qrtz_job_details ;
  7. DELETE FROM qrtz_calendars ;
  8. DELETE FROM qrtz_paused_trigger_grps ;
  9. DELETE FROM qrtz_scheduler_state ;
  10. DELETE FROM qrtz_locks ;
  11. DELETE FROM qrtz_fired_triggers
复制代码
Pom.xml
如果SpringBoot版本是2.0.0以后的,则在spring-boot-starter中已经包含了quart的依赖,则可以直接使用spring-boot-starter-quartz依赖:
  1. <dependency>
  2.     <groupId>org.springframework.boot</groupId>
  3.     <artifactId>spring-boot-starter-quartz</artifactId>
  4. </dependency>
  5. <dependency>
  6.     <groupId>mysql</groupId>
  7.     <artifactId>mysql-connector-java</artifactId>
  8.     <version>5.0.8</version>
  9. </dependency>
  10. <dependency>
  11.     <groupId>com.alibaba</groupId>
  12.     <artifactId>druid</artifactId>
  13.     <version>1.1.20</version>
  14. </dependency>
  15. <dependency>
  16.     <groupId>org.mybatis.spring.boot</groupId>
  17.     <artifactId>mybatis-spring-boot-starter</artifactId>
  18. </dependency>
  19. <dependency>
  20.     <groupId>cn.hutool</groupId>
  21.     <artifactId>hutool-all</artifactId>
  22.     <version>5.3.7</version>
  23. </dependency>
复制代码

QuartzJob 参考上图,建立实体
点击查看代码
  1. package com.vipsoft.web.entity;
  2. import javax.validation.constraints.NotBlank;
  3. import javax.validation.constraints.Size;
  4. import java.io.Serializable;
  5. /**
  6. * 定时任务调度
  7. */
  8. public class QuartzJob implements Serializable {
  9.     private static final long serialVersionUID = -6798153039624729495L;
  10.     /**
  11.      * 任务序号
  12.      */
  13.     private int jobId;
  14.     /**
  15.      * 任务名称
  16.      */
  17.     @NotBlank(message = "任务名称不能为空")
  18.     @Size(max = 10, message = "任务名称不能超过10个字符")
  19.     private String jobName;
  20.     /**
  21.      * 任务组名
  22.      */
  23.     @NotBlank(message = "任务组名不能为空")
  24.     @Size(max = 10, message = "任务组名不能超过10个字符")
  25.     private String jobGroup;
  26.     /**
  27.      * 调用目标字符串
  28.      */
  29.     private String invokeTarget;
  30.     /**
  31.      * 执行表达式
  32.      */
  33.     private String cronExpression;
  34.     /**
  35.      * cron计划策略 0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行
  36.      */
  37.     private String misfirePolicy = "0";
  38.     /**
  39.      * 并发执行 0=允许,1=禁止
  40.      */
  41.     private String concurrent;
  42.     /**
  43.      * 描述 -- 任务说明
  44.      */
  45.     private String description;
  46.     /**
  47.      * 任务状态(0正常 1暂停)
  48.      */
  49.     private String status;
  50.     public int getJobId() {
  51.         return jobId;
  52.     }
  53.     public void setJobId(int jobId) {
  54.         this.jobId = jobId;
  55.     }
  56.     public String getJobName() {
  57.         return jobName;
  58.     }
  59.     public void setJobName(String jobName) {
  60.         this.jobName = jobName;
  61.     }
  62.     public String getJobGroup() {
  63.         return jobGroup;
  64.     }
  65.     public void setJobGroup(String jobGroup) {
  66.         this.jobGroup = jobGroup;
  67.     }
  68.     public String getInvokeTarget() {
  69.         return invokeTarget;
  70.     }
  71.     public void setInvokeTarget(String invokeTarget) {
  72.         this.invokeTarget = invokeTarget;
  73.     }
  74.     public String getCronExpression() {
  75.         return cronExpression;
  76.     }
  77.     public void setCronExpression(String cronExpression) {
  78.         this.cronExpression = cronExpression;
  79.     }
  80.     public String getMisfirePolicy() {
  81.         return misfirePolicy;
  82.     }
  83.     public void setMisfirePolicy(String misfirePolicy) {
  84.         this.misfirePolicy = misfirePolicy;
  85.     }
  86.     public String getConcurrent() {
  87.         return concurrent;
  88.     }
  89.     public void setConcurrent(String concurrent) {
  90.         this.concurrent = concurrent;
  91.     }
  92.     public String getStatus() {
  93.         return status;
  94.     }
  95.     public void setStatus(String status) {
  96.         this.status = status;
  97.     }
  98.     public String getDescription() {
  99.         return description;
  100.     }
  101.     public void setDescription(String description) {
  102.         this.description = description;
  103.     }
  104. }
复制代码
核心代码:QuartzJobServiceImpl
点击查看代码[code]package com.vipsoft.web.service.impl;import cn.hutool.core.util.StrUtil;import com.vipsoft.web.config.ScheduleConstants;import com.vipsoft.web.entity.QuartzJob;import com.vipsoft.web.exception.CustomException;import com.vipsoft.web.job.CommonJob;import com.vipsoft.web.service.IQuartzJobService;import org.quartz.*;import org.quartz.impl.matchers.GroupMatcher;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.ArrayList;import java.util.List;import java.util.Set;@Servicepublic class QuartzJobServiceImpl implements IQuartzJobService {    @Autowired    Scheduler scheduler;    /**     * 新增任务     *     * @param job 调度信息     * @return 结果     */    @Override    public void clearAll(QuartzJob job) throws SchedulerException {        scheduler.clear();    }    /**     * 新增任务     *     * @param job 调度信息     * @return 结果     */    @Override    public void addJob(QuartzJob job) throws SchedulerException {        if (StrUtil.isEmpty(job.getStatus())) {            // 如果没值,设置暂停            job.setStatus(ScheduleConstants.Status.PAUSE.getValue());        }        Class

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

温锦文欧普厨电及净水器总代理

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表