spring quartz动态实现对任务的增删改查

        最近在做项目的时候用到了定时任务,而且用到的地方比较多,如果用配置文件配置的话,感觉不太方便,调整任务的执行方式也十分麻烦,因此,我采用了动态添加的方式,将定时任务保存在数据库中,这样既可以方便定时任务的添加,有能够随时改变、关闭定时任务。

      定时任务的主要实现逻辑是在初始化完spring之后初始化定时任务,添加、修改定时任务时,调用相应的方法去修改定时任务不多说,直接上核心代码:

    核心类:QuartzJobFactory

package com.thinkgem.jeesite.modules.task.quartz;

import java.util.List;

import org.apache.log4j.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;

import com.thinkgem.jeesite.common.utils.SpringContextHolder;
import com.thinkgem.jeesite.modules.task.dao.ScheduleJobDao;
import com.thinkgem.jeesite.modules.task.entity.ScheduleJob;
import com.thinkgem.jeesite.modules.task.quartz.uils.QuartzUtils;
 
/**
 * 定时任务运行工厂类
 * 
 */
public class QuartzJobFactory {// 实现的是无状态的Job
 
    private static Logger logger = Logger.getLogger(QuartzJobFactory.class);
    
    private static ScheduleJobDao scheduleJobDao = SpringContextHolder.getBean(ScheduleJobDao.class);
 
    /**
     * @Note : 初始化定时任务
     */
    public static void arrageScheduleJob() {
        try {
 
            List<ScheduleJob> jobList = scheduleJobDao.findList(new ScheduleJob());
            if (jobList.size() != 0) {
                for (ScheduleJob job : jobList) {
                    // Keys are composed of both a name and group, and the name  must be unique within the group
                    TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
                    // 获取trigger
                    CronTrigger trigger = (CronTrigger) QuartzUtils.scheduler.getTrigger(triggerKey);
                    // 不存在,创建一个
                    if (null == trigger) {
                        createSheduler(QuartzUtils.scheduler, job);
                    } else {// Trigger已存在,那么更新相应的定时设置
                        updateScheduler(QuartzUtils.scheduler, job, triggerKey, trigger);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * 更新相应的定时设置 根据job_status做相应的处理
     * 
     * @param scheduler
     * @param job
     * @param triggerKey
     * @param trigger
     * @throws SchedulerException
     */
    private static void updateScheduler(Scheduler scheduler, ScheduleJob job, TriggerKey triggerKey, CronTrigger trigger)
            throws SchedulerException {
        if (job.getJobStatus().equals("1")) {// 0禁用 1启用
            if (!trigger.getCronExpression().equalsIgnoreCase(job.getCronExpression())) {
                // 表达式调度构建器
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
                // 按新的cronExpression表达式重新构建trigger
                trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
                // 按新的trigger重新设置job执行
                scheduler.rescheduleJob(triggerKey, trigger);
                logger.info(job.getJobGroup() + "." + job.getJobName() + " 更新完毕,目前cron表达式为:" + job.getCronExpression()
                        + " isSpringBean:" + job.getIsSpringBean() + " concurrent: " + job.getConcurrent());
            }
        } else if (job.getJobStatus().equals("0")) {
            scheduler.pauseTrigger(triggerKey);// 停止触发器
            scheduler.unscheduleJob(triggerKey);// 移除触发器
            scheduler.deleteJob(trigger.getJobKey());// 删除任务
            logger.info(job.getJobGroup() + "." + job.getJobName() + "删除完毕");
        }
 
    }
 
    /**
     * 创建一个定时任务,并做安排
     * 
     * @param scheduler
     * @param job
     * @throws SchedulerException
     * @throws Exception
     */
    public static void createSheduler(Scheduler scheduler, ScheduleJob job) throws Exception {
        // 在工作状态可用时,即job_status = 1 ,开始创建
        if (job.getJobStatus().equals("1")) {
            // 新建一个基于Spring的管理Job类
            MethodInvokingJobDetailFactoryBean methodInvJobDetailFB = new MethodInvokingJobDetailFactoryBean();
            // 设置Job名称
            methodInvJobDetailFB.setName(job.getJobName());
            // 定义的任务类为Spring的定义的Bean则调用 getBean方法
            if (job.getIsSpringBean().equals("1")) {// 是Spring中定义的Bean
                methodInvJobDetailFB
                        .setTargetObject(SpringContextHolder.getBean(job.getTargetObject()));
            } else {// 不是
                methodInvJobDetailFB.setTargetObject(Class.forName(job.getClazz()).newInstance());
            }
            // 设置任务方法
            methodInvJobDetailFB.setTargetMethod(job.getTargetMethod());
            // 将管理Job类提交到计划管理类
            methodInvJobDetailFB.afterPropertiesSet();
            /** 并发设置 */
            methodInvJobDetailFB.setConcurrent(job.getConcurrent().equals("1") ? true : false);
 
            JobDetail jobDetail = methodInvJobDetailFB.getObject();// 动态
            jobDetail.getJobDataMap().put("scheduleJob", job);
            //jobName存入到队列 每隔一段时间就会扫描所以需要时检测
            if(!QuartzUtils.jobNames.contains(job.getJobName())){
                QuartzUtils.jobNames.add(job.getJobName());
            }
 
            // 表达式调度构建器
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
            // 按新的cronExpression表达式构建一个新的trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(job.getJobName(), job.getJobGroup())
                    .withSchedule(scheduleBuilder).build();
 
            scheduler.scheduleJob(jobDetail, trigger);// 注入到管理类
            logger.info(job.getJobGroup() + "." + job.getJobName() + "创建完毕");
        }
    }
    
    
    /**
     * 更新相应的定时设置 根据job_status做相应的处理
     * 
     * @param scheduler
     * @param job
     * @param triggerKey
     * @param trigger
     * @throws SchedulerException
     */
    public static void updateScheduler(ScheduleJob job)
            throws Exception {
    	Scheduler scheduler = QuartzUtils.scheduler;
    	TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
        // 获取trigger
        CronTrigger trigger = (CronTrigger) QuartzUtils.scheduler.getTrigger(triggerKey);
        // 不存在,创建一个
        if (null == trigger) {
        	createSheduler(scheduler, job);
        	return;
        }
        if (job.getJobStatus().equals("1")) {// 0禁用 1启用
            if (!trigger.getCronExpression().equalsIgnoreCase(job.getCronExpression())) {
                // 表达式调度构建器
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
                // 按新的cronExpression表达式重新构建trigger
                trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
                // 按新的trigger重新设置job执行
                scheduler.rescheduleJob(triggerKey, trigger);
                logger.info(job.getJobGroup() + "." + job.getJobName() + " 更新完毕,目前cron表达式为:" + job.getCronExpression()
                        + " isSpringBean:" + job.getIsSpringBean() + " concurrent: " + job.getConcurrent());
            }
        } else if (job.getJobStatus().equals("0")) {
            scheduler.pauseTrigger(triggerKey);// 停止触发器
            scheduler.unscheduleJob(triggerKey);// 移除触发器
            scheduler.deleteJob(trigger.getJobKey());// 删除任务
            logger.info(job.getJobGroup() + "." + job.getJobName() + "删除完毕");
        }
 
    }
    
    
    /**
     * 删除定时任务
     * 
     * @param scheduler
     * @param job
     * @param triggerKey
     * @param trigger
     * @throws SchedulerException
     */
    public static void deleteScheduler(ScheduleJob job)
            throws Exception {
    	Scheduler scheduler = QuartzUtils.scheduler;
    	TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
        // 获取trigger
        CronTrigger trigger = (CronTrigger) QuartzUtils.scheduler.getTrigger(triggerKey);
        // 不存在,创建一个
        if (null == trigger) {
        	return;
        }
        scheduler.pauseTrigger(triggerKey);// 停止触发器
        scheduler.unscheduleJob(triggerKey);// 移除触发器
        scheduler.deleteJob(trigger.getJobKey());// 删除任务
        logger.info(job.getJobGroup() + "." + job.getJobName() + "删除完毕");
    }
 
}

在spring的配置文件中加入bean

    <!-- 加载完spring启动此方法 -->
    <bean class="com.thinkgem.jeesite.modules.task.quartz.InstantiationTracingBeanPostProcessor"></bean>
	
	
    <!-- 任务工厂,注入需注入scheduler -->
    <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" ></bean>

InstantiationTracingBeanPostProcessor,加载完spring调用的文件

package com.thinkgem.jeesite.modules.task.quartz;

import org.quartz.SchedulerException;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import com.thinkgem.jeesite.modules.task.elastic.JobInit;
import com.thinkgem.jeesite.modules.task.entity.ScheduleJob;
import com.thinkgem.jeesite.modules.task.quartz.uils.QuartzUtils;

public class InstantiationTracingBeanPostProcessor implements ApplicationListener<ContextRefreshedEvent> {
	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		if (event.getApplicationContext().getParent() == null) {// root
																// application
																// context
																// 没有parent,他就是老大.
			
			// 需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。
			QuartzJobFactory.arrageScheduleJob();
			
		}

	}
}


在做定时任务时,参考了一些文章:


点击打开链接


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值