quartz 可配置的定时服务

来源:互联网 发布:windows 网络访问权限 编辑:程序博客网 时间:2024/06/11 06:25

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

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 启动就想执行监听

@Servicepublic 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 0
原创粉丝点击