quartz 可配置的定时服务

一、可配置的定时服务先设计数据库表结构

CREATE TABLE `job` (
	`id` CHAR(36) NOT NULL,
	`name` VARCHAR(36) NOT NULL COMMENT '任务名',
	`bean_name` VARCHAR(100) NOT NULL COMMENT 'spring bean name',
	`execute_exp` VARCHAR(200) NOT NULL COMMENT '执行的表达式',
	`state` INT(11) NOT NULL DEFAULT '1' COMMENT '1有效2无效',
	`remark` VARCHAR(100) NULL DEFAULT '1' COMMENT '描述信息',
	`create_time` DATETIME NOT NULL,
	PRIMARY KEY (`id`)
)
二、定义QuartzManager 管理器 可以使得注入可用
public class QuartzManager {
    private static SchedulerFactory sf                         = null;
    private static String           Default_JOB_GROUP_NAME     = "job_group";
    private static String           Default_TRIGGER_GROUP_NAME = "job_trigger";
    
    static {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        if (classLoader == null) {
            classLoader = QuartzManager.class.getClassLoader();
        }
        
        // 加载属性文件app.properties
        InputStream is = null;
        try {
            is = classLoader.getResourceAsStream("conf/quartz.properties");
            Properties properties = new Properties();
            properties.load(is);
            is.close();
            is = null;
            sf = new StdSchedulerFactory(properties);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
    
    /**
     * 添加任务
     * 
     * @param jobName
     * @param triggerName
     * @param jobClass
     * @param time
     * @return
     * @throws SchedulerException
     * @throws ParseException
     */
    public static JobDetail addJob(String jobId, String triggerName, String beanName, Class<? extends Job> jobClass,
            String time) throws SchedulerException, ParseException {
        Scheduler sched = sf.getScheduler();
        JobDetail jobDetail = newJob(jobClass).withIdentity(jobId, Default_JOB_GROUP_NAME).build();// 任务名,任务组,任务执行类
        jobDetail.getJobDataMap().put("beanName", beanName);
        jobDetail.getJobDataMap().put("jobId", jobId);
        CronTrigger trigger = newTrigger().withIdentity(triggerName, Default_TRIGGER_GROUP_NAME)
                .withSchedule(cronSchedule(time)).build();
        sched.scheduleJob(jobDetail, trigger);
        if (!sched.isShutdown()) sched.start();
        return jobDetail;
    }
    
    public static List<? extends Trigger> getTriggerKeys(JobKey jobKey) throws SchedulerException {
        return sf.getScheduler().getTriggersOfJob(jobKey);
    }
    
    /**
     * 触发一个任务
     * 
     * @param jobKey
     * @throws SchedulerException
     */
    public static void triggerJob(JobKey jobKey) throws SchedulerException {
        sf.getScheduler().triggerJob(jobKey);
    }
    
    /**
     * 得到一个触发器的任务状态
     * 
     * @param triggerKey
     * @return
     * @throws SchedulerException
     */
    public static TriggerState getTriggerState(TriggerKey triggerKey) throws SchedulerException {
        return sf.getScheduler().getTriggerState(triggerKey);
    }
    
    /**
     * 移除任务
     * 
     * @param jobName
     * @param triggerName
     * @param jobClass
     * @param time
     * @return
     * @throws SchedulerException
     * @throws ParseException
     */
    public static void removeJob(JobKey jobKey) throws SchedulerException {
        Scheduler sched = sf.getScheduler();
        sched.pauseJob(jobKey);
        sched.deleteJob(jobKey);
    }
    
    public static void clearAll() throws SchedulerException {
        Scheduler sched = sf.getScheduler();
        sched.clear();
        sched.shutdown();
    }
}
三、定义接口类

public interface IQuartzBaseJobService {
    public boolean execute(Job job);
}
四、每个新的beanName 实现 IQuartzBaseJobService走自己的逻辑

五、考虑到每个接口只实现,自己的业务不能加日志等信息,需要定义一个类来完成这事

public class QuartzSpringBeanJob implements org.quartz.Job {
    private final Logger logger = LoggerFactory.getLogger(QuartzSpringBeanJob.class);
    
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        JobDetail job = context.getJobDetail();
        String jobId = job.getJobDataMap().getString("jobId");
        String jobBeanName = job.getJobDataMap().getString("beanName");
        if (StringUtils.isEmpty(jobId) || StringUtils.isEmpty(jobBeanName)) {
            return;
        }
        boolean success = true;
        String message = "";
        // 检查当前job是否可以执行
        IJobService jobService = SpringContextHolder.getBean("jobService");
        Job jobBean = jobService.findUnique(jobId);
        if (jobBean == null || jobBean.getState() != BooleanEnum.True.getValue()) {
            try {
                QuartzManager.removeJob(job.getKey());
            } catch (SchedulerException e) {
                logger.error(e.getMessage(), e);
                e.printStackTrace();
            }
            return;
        }
        IJobLogService jobLogService = SpringContextHolder.getBean("jobLogService");
        // 查询上一次是否已经执行成功
        boolean existsDoing = jobLogService.existsUnComplete(jobId);
        
        // 生成job日志
        JobLog jobLog = new JobLog();
        jobLog.setId(GuidKeyGenerator.getUUIDKey());
        jobLog.setJobId(jobId);
        jobLog.setStartTime(new Date());
        if(!existsDoing){
            jobLog.setState(JobLogStateEnum.Doing.getValue());
        } else {
            jobLog.setState(JobLogStateEnum.UnStart.getValue());
            jobLog.setMessage("上次未执行结束!本次不再执行!");
        }
        jobLogService.create(jobLog);
        if(existsDoing){// 还有没有执行完的,就不再执行了
            return ;
        }
        
        try {
            IQuartzBaseJobService quartzBaseJobService = SpringContextHolder.getBean(jobBeanName);//为自己bean
            if (quartzBaseJobService != null) {
                quartzBaseJobService.execute(jobBean);
            }
        } catch (Exception e) {
            success = false;
            message = e.getMessage();
            logger.error(e.getMessage(), e);
        }
        // 更新日志状态
        JobLog newJobLog = new JobLog();
        newJobLog.setId(jobLog.getId());
        newJobLog.setState(success ? JobLogStateEnum.Success.getValue() : JobLogStateEnum.Error.getValue());
        newJobLog.setEndTime(new Date());
        newJobLog.setMessage(message);
        jobLogService.update(newJobLog, jobLog);
    }
    
六、一般spring 启动就想执行监听

@Service
public class JobTaskService implements IJobTaskService, Initalizer {
    private final Logger                        logger       = LoggerFactory.getLogger(JobTaskService.class);
    
    private final static Map<String, JobDetail> jobDetailMap = new HashMap<String, JobDetail>();
    
    @Autowired
    private IJobService                         jobService;
    @Autowired
    private IJobLogService                      jobLogService;
    
    @Override
    public void initalize() {
        jobLogService.clearDoing();
        startAll();
    }
    
    private void startAll() {
        List<Job> jobs = jobService.findValid();
        if (jobs == null) return;
        for (Job job : jobs) {
            try {
                JobDetail jobDetail = QuartzManager.addJob(job.getId(), "trigger-" + job.getId(), job.getBeanName(),
                        QuartzSpringBeanJob.class, job.getExecuteExp());
                jobDetailMap.put(job.getId(), jobDetail);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("addJobError:jobId:" + job.getId() + e.getMessage(), e);
            }
        }
    }
}
七、考虑到新增修改删除,所以我把我用的方法列
public static void removeJob(String jobName) throws SchedulerException{  
        try {  
            Scheduler sched = sf.getScheduler();
            sched.pauseTrigger(new TriggerKey(jobName, Default_TRIGGER_GROUP_NAME));// 停止触发器  
            sched.unscheduleJob(new TriggerKey(jobName, Default_TRIGGER_GROUP_NAME));// 移除触发器  
            sched.deleteJob(new JobKey(jobName, Default_JOB_GROUP_NAME));// 删除任务  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
    
    
    public static void modifyJobTime(String triggerName,  
            String triggerGroupName, String time) {  
        try {  
            Scheduler sched = sf.getScheduler();
            TriggerKey triggerKey = new TriggerKey(triggerName,Default_TRIGGER_GROUP_NAME);
			CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);  
			CronScheduleBuilder scheduleBuilder = cronSchedule(time);
            if (trigger == null) {  
                return;  
            }  
            String oldTime = trigger.getCronExpression();  
            if (!oldTime.equalsIgnoreCase(time)) {
            	trigger = trigger.getTriggerBuilder().withIdentity(triggerKey)
            			.withSchedule(scheduleBuilder).build();

            	//按新的trigger重新设置job执行
            	sched.rescheduleJob(triggerKey, trigger);
            }  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        }  
    }  
    
    public static void clearAll() throws SchedulerException {
        Scheduler sched = sf.getScheduler();
        sched.clear();
        sched.shutdown();
    }   
<pre name="code" class="java">    /**
     * 触发一个任务
     * 
     * @param jobKey
     * @throws SchedulerException
     */
    public static void triggerJob(JobKey jobKey) throws SchedulerException {
        sf.getScheduler().triggerJob(jobKey);
    }


 八、总结一下 

Trigger 就是个触发器 jobDetail 就是那个类要作这件事情

scheduler 一个工厂对象返回,作什么事几点作就可以了。

scheduler.start();

成了




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值