• Spring 3整合Quartz 2实现定时任务:动态添加任务


    先展示一下后台管理定时任务效果图:

    1、新增任务页面:

     

    2、列表页(实现任务的禁用启用)

    3、数据库脚本:

    -- ----------------------------
    -- Table structure for schedule_job
    -- ----------------------------
    DROP TABLE IF EXISTS `schedule_job`;
    CREATE TABLE `schedule_job` (
    `jobid` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务ID',
    `jobname` varchar(40) DEFAULT NULL COMMENT '任务名称',
    `jobgroup` varchar(40) DEFAULT NULL COMMENT '任务分组',
    `jobstatus` char(1) NOT NULL DEFAULT '1' COMMENT '任务状态 0禁用 1启用',
    `auditstatus` char(1) NOT NULL DEFAULT '0' COMMENT '审核状态 0 已创建 1 审核通过 2 审核驳回',
    `cronexpression` varchar(40) NOT NULL COMMENT '任务运行时间表达式',
    `quartzclass` varchar(255) DEFAULT NULL COMMENT '定时任务处理类',
    `description` varchar(280) DEFAULT NULL COMMENT '描述信息',
    PRIMARY KEY (`jobid`)
    ) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8;

    4、定时任务后台处理类(核心):

    package com.eb.admin.schedule;

    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;

    import org.quartz.CronScheduleBuilder;
    import org.quartz.CronTrigger;
    import org.quartz.Job;
    import org.quartz.JobBuilder;
    import org.quartz.JobDetail;
    import org.quartz.JobKey;
    import org.quartz.Scheduler;
    import org.quartz.TriggerBuilder;
    import org.quartz.TriggerKey;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.scheduling.quartz.SchedulerFactoryBean;
    import org.springframework.stereotype.Component;

    import com.eb.admin.entity.ScheduleJob;
    import com.eb.admin.service.ConfigService;

    /**
    * 调度工厂类
    *
    * @author Jason.Yan
    * @since 2018/03/28
    *
    */
    @Configuration
    @EnableScheduling
    @Component
    public class ScheduleFactory {

    private static Logger logger = LoggerFactory.getLogger(ScheduleFactory.class);

    private Map<String, String> jobUniqueMap = new HashMap<String, String>(); // 当前Trigger使用的

    @Autowired
    private SchedulerFactoryBean schedulerFactoryBean;

    public SchedulerFactoryBean getSchedulerFactoryBean() {
    return schedulerFactoryBean;
    }

    public void setSchedulerFactoryBean(SchedulerFactoryBean schedulerFactoryBean) {
    this.schedulerFactoryBean = schedulerFactoryBean;
    }

    @Autowired
    private ConfigService configService;

    public ConfigService getConfigService() {
    return configService;
    }

    public void setConfigService(ConfigService configService) {
    this.configService = configService;
    }

    //TODO 此处暂且注释,后续有后台定时任务逻辑 开启
    @Scheduled(fixedRate = 5000) // 每隔5s查库,并根据查询结果决定是否重新设置定时任务
    public void scheduleUpdateCronTrigger() throws Exception {

    try {
    // schedulerFactoryBean 由spring创建注入
    Scheduler scheduler = schedulerFactoryBean.getScheduler();
    List<ScheduleJob> jobList = configService.findLegalJobList();

    // 获取最新删除(禁用)任务列表,将其从调度器中删除,并且从jobUniqueMap中删除
    List<ScheduleJob> jobDelList = configService.findDelJobList();
    for (ScheduleJob delJob : jobDelList) {
    JobKey jobKey = JobKey.jobKey(delJob.getJobName(), delJob.getJobGroup());
    scheduler.deleteJob(jobKey);
    jobUniqueMap.remove(TriggerKey.triggerKey(delJob.getJobName(), delJob.getJobGroup()));
    }

    for (ScheduleJob job : jobList) {

    TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
    // 获取trigger,即在spring配置文件中定义的 bean id="myTrigger"
    CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

    String dbCron = job.getCronExpression(); // 该job数据库中的Trigger表达式
    // 不存在,创建一个
    if (null == trigger) {
    //JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class).withIdentity(job.getJobName(), job.getJobGroup()).build();
    try{
    @SuppressWarnings("unchecked")
    Class <? extends Job> clazz = (Class<? extends Job>) Class.forName(job.getQuartzClass());
    JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(job.getJobName(), job.getJobGroup()).build();
    jobDetail.getJobDataMap().put("scheduleJob", job);
    // 表达式调度构建器
    CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
    // 按新的cronExpression表达式构建一个新的trigger
    trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();

    jobUniqueMap.put(triggerKey.toString(), trigger.getCronExpression());
    //currentCron = trigger.getCronExpression();

    scheduler.scheduleJob(jobDetail, trigger);
    }catch(Exception e){
    e.printStackTrace();
    logger.error(e.getMessage());
    }

    } else if(!jobUniqueMap.get(triggerKey.toString()).equals(dbCron)){
    // Trigger已存在,那么更新相应的定时设置
    // 表达式调度构建器
    CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(dbCron);
    // 按新的cronExpression表达式重新构建trigger

    trigger = (CronTrigger) scheduler.getTrigger(triggerKey);

    trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
    // 按新的trigger重新设置job执行
    scheduler.rescheduleJob(triggerKey, trigger);

    jobUniqueMap.put(triggerKey.toString(), dbCron);
    }
    }

    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

    5、后台查询sql:

    ConfigService.findLegalJobList=select * from schedule_job where jobstatus = 1 and auditstatus = 1

    ConfigService.findDelJobList=select * from schedule_job where jobstatus = 0

    6、后台查询方法实现类:

    package com.eb.admin.service.impl;

    import java.util.List;

    import com.eb.admin.entity.ScheduleJob;
    import com.eb.admin.service.ConfigService;
    import com.eb.dataservice.dao.CommonDao;
    import com.eb.dataservice.dao.SqlUtils;

    public class ConfigServiceImpl implements ConfigService {

    @SuppressWarnings("unchecked")
    @Override
    public List<ScheduleJob> findLegalJobList() throws Exception {
    CommonDao dao = CommonDao.getDao(dbkey);
    String sql = SqlUtils.getSql("ConfigService.findLegalJobList");
    return dao.findBeanList(ScheduleJob.class, sql);
    }

    @Override
    public List<ScheduleJob> findDelJobList() throws Exception {
    CommonDao dao = CommonDao.getDao(dbkey);
    String sql = SqlUtils.getSql("ConfigService.findDelJobList");
    return dao.findBeanList(ScheduleJob.class, sql);
    }

    }

    以上为本人根据两篇博文所做的整理修改,原文参见:

    https://blog.csdn.net/liuchuanhong1/article/details/60873295#reply

    https://www.ktanx.com/blog/p/308

    本着尊重原作者的态度,转载请注明出处:

    http://www.cnblogs.com/Ivan-j2ee/p/8697054.html

  • 相关阅读:
    ranger0.5.4-开源安装配置
    Spark Streaming 读取Kafka数据写入ES
    kettle与sqoop的比较
    spark常用算子
    eclipse快捷键
    hive相关操作
    我眼中如何成为一名合格PHP高级开发工程师
    laravel 路由404
    TP5.0 未定义变量
    公众号基本配置(token验证失败)|公众平台测试账号接口配置信息(token验证失败)
  • 原文地址:https://www.cnblogs.com/Ivan-j2ee/p/8697054.html
Copyright © 2020-2023  润新知