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

posted @ 2019-01-11 16:20  KitFung-P  阅读(2642)  评论(0编辑  收藏  举报