Java下Spring实现Quartz集群分布式(四)

一、序言

Java下Spring实现Quartz集群分布式(一)中的QuartzService 的源码

二、正文

QuartzService 的源代码:

package wade.system.service;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.quartz.*;

/**
 * 定时任务管理
 *
 */
public interface QuartzService {

    /**
     * 添加定时任务
     *
     * @param name              the name
     * @param group             the group
     * @param clazz             the clazz
     * @param cronExpression    the cron expression
     * @param jobValue          the job value
     * @param scheduler         the scheduler
     * @param isJobListened     the is job listened
     * @param isTriggerListened the is trigger listened
     * @return the date
     * @throws IllegalAccessException the illegal access exception
     * @throws InstantiationException the instantiation exception
     * @throws ClassNotFoundException the class not found exception
     * @throws SchedulerException     the scheduler exception
     */
    Date addJob(String name, String group, Class<? extends Job> clazz, String cronExpression,
                Map<String, String> jobValue, Scheduler scheduler, boolean isJobListened, boolean isTriggerListened)
            throws IllegalAccessException, InstantiationException, ClassNotFoundException, SchedulerException;

    /**
     * Add job by simple trigger date.
     *
     * @param name              the name
     * @param group             the group
     * @param clazz             the clazz
     * @param simpleTrigger     the simple trigger
     * @param jobValue          the job value
     * @param scheduler         the scheduler
     * @param isJobListened     the is job listened
     * @param isTriggerListened the is trigger listened
     * @return the date
     * @throws SchedulerException     the scheduler exception
     * @throws IllegalAccessException the illegal access exception
     * @throws InstantiationException the instantiation exception
     * @throws ClassNotFoundException the class not found exception
     */
    Date addJobBySimpleTrigger(String name, String group, Class<? extends Job> clazz, Trigger simpleTrigger,
                               Map<String, String> jobValue, Scheduler scheduler,
                               boolean isJobListened, boolean isTriggerListened)
            throws SchedulerException, IllegalAccessException, InstantiationException, ClassNotFoundException;

    /**
     * 立即执行一次
     *
     * @param name              the name
     * @param group             the group
     * @param clazz             the clazz
     * @param jobValue          the job value
     * @param scheduler         the scheduler
     * @param isJobListened     the is job listened
     * @param isTriggerListened the is trigger listened
     * @throws SchedulerException     the scheduler exception
     * @throws IllegalAccessException the illegal access exception
     * @throws InstantiationException the instantiation exception
     * @throws ClassNotFoundException the class not found exception
     */
    void immediatelyExecuteJobOneTime(String name, String group, Class<? extends Job> clazz,
                                      Map<String, String> jobValue, Scheduler scheduler,
                                      boolean isJobListened, boolean isTriggerListened)
            throws SchedulerException, IllegalAccessException, InstantiationException, ClassNotFoundException;

    /**
     * 删除定时任务
     *
     * @param name      the name
     * @param group     the group
     * @param scheduler the scheduler
     * @throws SchedulerException the scheduler exception
     */
    void removeJob(String name, String group, Scheduler scheduler) throws SchedulerException;

    /**
     * 暂停定时任务
     *
     * @param name      the name
     * @param group     the group
     * @param scheduler the scheduler
     * @throws SchedulerException the scheduler exception
     */
    void pauseJob(String name, String group, Scheduler scheduler) throws SchedulerException;

    /**
     * 重新开始定时任务
     *
     * @param name      the name
     * @param group     the group
     * @param scheduler the scheduler
     * @throws SchedulerException the scheduler exception
     */
    void resumeJob(String name, String group, Scheduler scheduler) throws SchedulerException;

    /**
     * 修改定时任务时间
     *
     * @param name           the name
     * @param group          the group
     * @param cronExpression the cron expression
     * @param scheduler      the scheduler
     * @return the date
     * @throws SchedulerException the scheduler exception
     */
    Date modifyTime(String name, String group,
                    String cronExpression, Scheduler scheduler) throws SchedulerException;

    /**
     * 修改定时任务的时间和参数
     *
     * @param name           the name
     * @param group          the group
     * @param clazz          the clazz
     * @param cronExpression the cron expression
     * @param jobValue       the job value
     * @param scheduler      the scheduler
     * @param isJobListener  the is job listener
     * @return the date
     * @throws SchedulerException     the scheduler exception
     * @throws IllegalAccessException the illegal access exception
     * @throws InstantiationException the instantiation exception
     * @throws ClassNotFoundException the class not found exception
     */
    Date modifyJobValueAndTime(String name,
                               String group,
                               Class<? extends Job> clazz,
                               String cronExpression,
                               Map<String, String> jobValue,
                               Scheduler scheduler, boolean isJobListener) throws SchedulerException,
            IllegalAccessException, InstantiationException, ClassNotFoundException;

    /**
     * 任务开始
     *
     * @param scheduler the scheduler
     * @throws SchedulerException the scheduler exception
     */
    void start(Scheduler scheduler) throws SchedulerException;

    /**
     * 任务关闭
     *
     * @param scheduler the scheduler
     * @throws SchedulerException the scheduler exception
     */
    void shutdown(Scheduler scheduler) throws SchedulerException;

    /**
     * 获取下次执行时间
     *
     * @param name      the name
     * @param group     the group
     * @param scheduler the scheduler
     * @return the next fire time
     * @throws SchedulerException the scheduler exception
     */
    Date getNextExecutionTime(String name, String group, Scheduler scheduler) throws SchedulerException;

    /**
     * 检查作业是否正在执行
     *
     * @param key       the key
     * @param scheduler the scheduler
     * @return the boolean
     * @throws SchedulerException the scheduler exception
     */
    boolean checkJobStatus(String key, Scheduler scheduler) throws SchedulerException;

    /**
     * 初始化所有的jobListener
     *
     * @return boolean
     */
    boolean initALLJobListener(List<JobKey> jobKeyList);

    /**
     * 根据组来初始化JobListener
     *
     * @param groups key为GROUP名字,value为监听器路径
     * @return
     */
    boolean initGroupJobListener(Map<String, String> groups);
} 

QuartzServiceImpl的源代码:

package wade.system.service.impl;


import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

import java.util.*;

import org.apache.commons.lang3.StringUtils;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.quartz.impl.matchers.KeyMatcher;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import wade.system.service.QuartzService;



@Repository("quartzService")
public class QuartzServiceImpl implements QuartzService {

    /**
     * 日志记录
     */
    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(QuartzServiceImpl.class);
    /**
     * 调度程序工厂类
     */
    @Autowired
    SchedulerFactoryBean schedulerFactoryBean;

    @Override
    public Date addJob(String name, String group, Class<? extends Job> clazz, String cronExpression,
                       Map<String, String> jobValue, Scheduler scheduler,
                       boolean isJobListened, boolean isTriggerListened)
            throws IllegalAccessException, InstantiationException, ClassNotFoundException, SchedulerException {
        Date nextFireTime = null;
        //构造任务
        JobDetail job = newJob(clazz).withIdentity(name, group).storeDurably(true).build();
        //构造任务触发器
        Trigger trg = newTrigger().withIdentity(name, group).withSchedule(cronSchedule(cronExpression)
                .withMisfireHandlingInstructionDoNothing ()).build();
        if (jobValue != null) {
            for (String key : jobValue.keySet()) {
                job.getJobDataMap().put(key, jobValue.get(key));
            }
        }
        isJobListened = false;
        if (isJobListened) {
            scheduler = addJobListener(job.getKey(), clazz, scheduler);
        }
        if (isTriggerListened) {
            scheduler = addTriggerListened(trg, clazz, scheduler);
        }
        //将作业添加到调度器
        nextFireTime = scheduler.scheduleJob(job, trg);
        LOGGER.info("新增作业=> [作业名称:" + name + " 作业组:" + group + "] ");
        return nextFireTime;
    }

    @Override
    public void immediatelyExecuteJobOneTime(String name,
                                             String group,
                                             Class<? extends Job> clazz,
                                             Map<String, String> jobValue,
                                             Scheduler scheduler,
                                             boolean isJobListened,
                                             boolean isTriggerListened)
            throws SchedulerException, IllegalAccessException, InstantiationException, ClassNotFoundException {
        JobKey jobKey = new JobKey(name, group);
        JobDataMap jobDataMap = new JobDataMap();
        if (jobValue != null) {
            for (String key : jobValue.keySet()) {
                jobDataMap.put(key, jobValue.get(key));
            }
        }
        isJobListened = false;
        if (isJobListened) {
            scheduler = addJobListener(jobKey, clazz, scheduler);
        }
        scheduler.triggerJob(jobKey, jobDataMap);
    }

    @Override
    public boolean checkJobStatus(String key, Scheduler scheduler) throws SchedulerException {
        List<JobExecutionContext> jobExecutionContexts = scheduler.getCurrentlyExecutingJobs();
        for (JobExecutionContext job : jobExecutionContexts) {
            JobDetail jobDetail = job.getJobDetail();
            JobKey jobKey = jobDetail.getKey();
            if (jobKey.getName().equals(key)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 添加作业监听程序
     *
     * @param jobKey
     * @param clazz
     * @param scheduler
     */
    private Scheduler addJobListener(JobKey jobKey, Class<? extends Job> clazz, Scheduler scheduler) throws
            ClassNotFoundException, IllegalAccessException, InstantiationException, SchedulerException {
        String tempPath = clazz.getName() + "Listener";
        String listenerFilePath = buildEntirePath(tempPath);
        Object jobListener = Class.forName(listenerFilePath).newInstance();
        KeyMatcher<JobKey> keyMatcher = KeyMatcher.keyEquals(jobKey);
        scheduler.getListenerManager().addJobListener((JobListener) jobListener, keyMatcher);
        return scheduler;
    }

    private Scheduler addTriggerListened(Trigger trigger, Class<? extends Job> clazz, Scheduler scheduler)
            throws ClassNotFoundException, IllegalAccessException, InstantiationException, SchedulerException {
        String tempPath = clazz.getName() + "TListener";
        String listenerFilePath = buildEntirePath(tempPath);
        TriggerListener triggerListener = (TriggerListener) Class.forName(listenerFilePath).newInstance();
        KeyMatcher<TriggerKey> keyMatcher = KeyMatcher.keyEquals(trigger.getKey());
        scheduler.getListenerManager().addTriggerListener(triggerListener, keyMatcher);
        return scheduler;
    }

    /**
     * 构建完整的Listener文件路径
     *
     * @param tempPath
     * @return
     */
    private String buildEntirePath(String tempPath) {
        String[] packageNames = tempPath.split("\\.");
        List<String> list = new ArrayList<>();
        Arrays.asList(packageNames).forEach(s -> {
            list.add(s);
        });
        list.add(list.size() - 1, "listener");
        return StringUtils.join(list, ".");
    }

    @Override
    public Date addJobBySimpleTrigger(String name,
                                      String group,
                                      Class<? extends Job> clazz,
                                      Trigger simpleTrigger,
                                      Map<String, String> jobValue,
                                      Scheduler scheduler, boolean isJobListened, boolean isTriggerListened)
            throws SchedulerException, IllegalAccessException, InstantiationException, ClassNotFoundException {
        Date nextFireTime = null;
        //构造任务
        JobDetail job = newJob(clazz).withIdentity(name, group).build();
        if (jobValue != null) {
            for (String key : jobValue.keySet()) {
                job.getJobDataMap().put(key, jobValue.get(key));
            }
        }
        //将作业添加到调度器
        Trigger trigger = simpleTrigger;
        isJobListened = false;
        if (isJobListened) {
            scheduler = addJobListener(job.getKey(), clazz, scheduler);
        }
        if (isTriggerListened) {
            scheduler = addTriggerListened(trigger, clazz, scheduler);
        }
        nextFireTime = scheduler.scheduleJob(job, trigger);
        LOGGER.info("新增作业=> [作业名称:" + name + " 作业组:" + group + "] ");
        return nextFireTime;
    }

    @Override
    public void removeJob(String name, String group, Scheduler scheduler) throws SchedulerException {
        TriggerKey tk = TriggerKey.triggerKey(name, group);
        scheduler.pauseTrigger(tk);//停止触发器
        scheduler.unscheduleJob(tk);//移除触发器
        JobKey jobKey = JobKey.jobKey(name, group);
        scheduler.deleteJob(jobKey);//删除作业
        LOGGER.info("删除作业=> [作业名称:" + name + " 作业组:" + group + "] ");
    }

    @Override
    public void pauseJob(String name, String group, Scheduler scheduler) throws SchedulerException {

        JobKey jobKey = JobKey.jobKey(name, group);
        scheduler.pauseJob(jobKey);
        LOGGER.info("暂停作业=> [作业名称:" + name + " 作业组:" + group + "] ");
    }

    @Override
    public void resumeJob(String name, String group, Scheduler scheduler) throws SchedulerException {
        JobKey jobKey = JobKey.jobKey(name, group);
        scheduler.resumeJob(jobKey);
        LOGGER.info("恢复作业=> [作业名称:" + name + " 作业组:" + group + "] ");
    }

    @Override
    public Date modifyTime(String name, String group, String cronExpression, Scheduler scheduler)
            throws SchedulerException {
        TriggerKey tk = TriggerKey.triggerKey(name, group);
        //构造任务触发器
        Trigger trg = newTrigger().withIdentity(name, group)
                .forJob(name, group).withSchedule(cronSchedule(cronExpression)
                        .withMisfireHandlingInstructionDoNothing()).build();
        Date nextFireTime = scheduler.rescheduleJob(tk, trg);
        LOGGER.info("修改作业触发时间=> [作业名称:" + name + " 作业组:" + group + "] ");
        return nextFireTime;
    }

    @Override
    public Date modifyJobValueAndTime(String name,
                                      String group,
                                      Class<? extends Job> clazz,
                                      String cronExpression,
                                      Map<String, String> jobValue,
                                      Scheduler scheduler, boolean isJobListener) throws SchedulerException,
            IllegalAccessException, InstantiationException, ClassNotFoundException {
        TriggerKey oldTk = TriggerKey.triggerKey(name, group);
        scheduler.pauseTrigger(oldTk);//停止触发器
        scheduler.unscheduleJob(oldTk);//移除触发器
        JobKey jobKey = JobKey.jobKey(name, group);
        scheduler.deleteJob(jobKey);//删除作业
        Date nextFireTime = null;
        //构造任务
        JobDetail job = newJob(clazz).withIdentity(name, group).storeDurably(true).build();
        for (String key : jobValue.keySet()) {
            job.getJobDataMap().put(key, jobValue.get(key));
        }
        if (isJobListener) {
            scheduler = addJobListener(job.getKey(), clazz, scheduler);
        }
        //构造任务触发器
        Trigger trg = newTrigger().withIdentity(name, group)
                .forJob(job).withSchedule(cronSchedule(cronExpression)
                        .withMisfireHandlingInstructionDoNothing()).build();
        nextFireTime = scheduler.scheduleJob(job, trg);
        LOGGER.info("修改作业触发时间和参数=> [触发器名称:" + name + " 作业组:" + group + "] ");
        return nextFireTime;
    }

    @Override
    public void start(Scheduler scheduler) throws SchedulerException {
        scheduler.start();
        LOGGER.info("启动调度器 ");
    }

    @Override
    public void shutdown(Scheduler scheduler) throws SchedulerException {
        scheduler.shutdown();
        LOGGER.info("停止调度器 ");

    }

    @Override
    public Date getNextExecutionTime(String name, String group, Scheduler scheduler) throws SchedulerException {
        TriggerKey triggerKey = TriggerKey.triggerKey(String.valueOf(name), group);
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        return trigger.getNextFireTime();
    }

    @Override
    public boolean initALLJobListener(List<JobKey> jobKeyList) {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        boolean result = false;
        try {
            for (JobKey jobKey : jobKeyList) {
                JobDetail jd = scheduler.getJobDetail(jobKey);
                if (jd != null) {
                    LOGGER.info("my ID is " + jd.getKey() + "my Class is " + jd.getJobClass().toString());
                    addJobListener(jobKey, jd.getJobClass(), scheduler);
                }
            }
            result = true;
        } catch (Exception e) {
            LOGGER.error("批量绑定监听器异常", e);
        }
        return result;
    }

    @Override
    public boolean initGroupJobListener(Map<String, String> groups) {
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        boolean result = false;
        try {
            for (Map.Entry<String, String> entry : groups.entrySet()) {
                GroupMatcher<JobKey> groupMatcher = GroupMatcher.groupEquals(entry.getKey());
                Object clazz = Class.forName(entry.getValue()).newInstance();
                scheduler.getListenerManager().addJobListener((JobListener) clazz, groupMatcher);
                scheduler.getListenerManager().getJobListeners().forEach(jobListener -> {
                    LOGGER.info(jobListener.getName());
                });
            }
            result = true;
        } catch (Exception e) {
            LOGGER.error("批量绑定监听器异常", e);
        }
        return result;
    }
}

猜你喜欢

转载自blog.csdn.net/zengwende/article/details/87740817