Quartz源码节选(三)添加Job和Trigger到Scheduler中

参考资料

第一篇配合第二篇阅读,讲解一些基本概念。若已了解可跳过。
推荐阅读第三篇,因为本文是基于第三篇的笔记。

DEMO

一个DEMO,每3秒输出helloworld

public class MyJob implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        JobDataMap jobDataMap = context.getMergedJobDataMap();
        String say = jobDataMap.getString("say");
        System.out.println(say);
    }
}
public class Demo {
    public static void main(String[] args) {
        JobDetail jd = JobBuilder.newJob(MyJob.class)
                .withIdentity("myJob","jobGroup1")
                .withDescription("a demo jobDetail")
                .usingJobData("say","helloworld")
                .build();

        CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                .withIdentity("myCronTrigger","triggerGroup1")
                .withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ?"))
                .forJob(jd)
                .build();
        
        try {
            Scheduler scheduler = new StdSchedulerFactory().getScheduler(); 
            scheduler.scheduleJob(jd,cronTrigger);//本文要讲的部分
            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
}

StdScheduler和QuartzScheduler的关系

StdScheduler大部分方法都委托内部的QuartzScheduler实现,除了getMetaData()方法

public class StdScheduler implements Scheduler {
    private QuartzScheduler sched;
    /*
     *省略部分代码
     */
    public Date scheduleJob(JobDetail jobDetail, Trigger trigger)
        throws SchedulerException {
        return sched.scheduleJob(jobDetail, trigger);//实际由QuartzScheduler执行
    }
    /*
     *省略部分代码
     */
    public SchedulerMetaData getMetaData() {
        return new SchedulerMetaData(getSchedulerName(),
                getSchedulerInstanceId(), getClass(), false, isStarted(), 
                isInStandbyMode(), isShutdown(), sched.runningSince(), 
                sched.numJobsExecuted(), sched.getJobStoreClass(), 
                sched.supportsPersistence(), sched.isClustered(), sched.getThreadPoolClass(), 
                sched.getThreadPoolSize(), sched.getVersion());

    }
}

JobDetail和Trigger加入到调度中

既然是委托的,那可以直接看QuartzScheduler.scheduleJob(JobDetail jobDetail, Trigger trigger)

  • QuartzScheduler.scheduleJob(JobDetail jobDetail, Trigger trigger)
public Date scheduleJob(JobDetail jobDetail, Trigger trigger) throws SchedulerException {
    validateState();

    if (jobDetail == null) {
        throw new SchedulerException("JobDetail cannot be null");
    }

    if (trigger == null) {
        throw new SchedulerException("Trigger cannot be null");
    }

    if (jobDetail.getKey() == null) {
        throw new SchedulerException("Job's key cannot be null");
    }

    if (jobDetail.getJobClass() == null) {
        throw new SchedulerException("Job's class cannot be null");
    }

    OperableTrigger trig = (OperableTrigger)trigger;

    //这里的操作和TriggerBuilder.forJob()类似
    if (trigger.getJobKey() == null) { 
        trig.setJobKey(jobDetail.getKey());
    } else if (!trigger.getJobKey().equals(jobDetail.getKey())) {
        throw new SchedulerException(
            "Trigger does not reference given job!");
    }

    trig.validate();

    Calendar cal = null;
    if (trigger.getCalendarName() != null) {
        cal = resources.getJobStore().retrieveCalendar(trigger.getCalendarName());
    }
    Date ft = trig.computeFirstFireTime(cal);

    if (ft == null) {
        throw new SchedulerException(
            "Based on configured schedule, the given trigger '" + trigger.getKey() + "' will never fire.");
    }
    
    resources.getJobStore().storeJobAndTrigger(jobDetail, trig);//JobStore保存JobDetail和Trigger信息
    notifySchedulerListenersJobAdded(jobDetail);
    notifySchedulerThread(trigger.getNextFireTime().getTime());
    notifySchedulerListenersSchduled(trigger);

    return ft;
}

JobStore保存JobDetail和Trigger的信息

JobStore的一个基本功能是保存JobDetail和Trigger的信息。JobStroe多种实现。比如JobStoreSupport能将数据保存到数据库中,涉及一些数据库连接的操作,RAMJobStore将信息保存在内存中。

public class RAMJobStore implements JobStore {

    //按key分类
    protected HashMap<JobKey, JobWrapper> jobsByKey = new HashMap<JobKey, JobWrapper>(1000);
    protected HashMap<TriggerKey, TriggerWrapper> triggersByKey = new HashMap<TriggerKey, TriggerWrapper>(1000);
	//按group分类
    protected HashMap<String, HashMap<JobKey, JobWrapper>> jobsByGroup = new HashMap<String, HashMap<JobKey, JobWrapper>>(25);
    protected HashMap<String, HashMap<TriggerKey, TriggerWrapper>> triggersByGroup = new HashMap<String, HashMap<TriggerKey, TriggerWrapper>>(25);
	//TreeSet保证trigger不重复并能按照最优先的处理去排序
    protected TreeSet<TriggerWrapper> timeTriggers = new TreeSet<TriggerWrapper>(new TriggerWrapperComparator());

    protected HashMap<String, Calendar> calendarsByName = new HashMap<String, Calendar>(25);

    protected Map<JobKey, List<TriggerWrapper>> triggersByJob = new HashMap<JobKey, List<TriggerWrapper>>(1000);

    protected final Object lock = new Object();

    protected HashSet<String> pausedTriggerGroups = new HashSet<String>();
    protected HashSet<String> pausedJobGroups = new HashSet<String>();
    protected HashSet<JobKey> blockedJobs = new HashSet<JobKey>();
    
    protected long misfireThreshold = 5000l;
    protected SchedulerSignaler signaler;
    private final Logger log = LoggerFactory.getLogger(getClass());
  • RAMJobStore.storeJobAndTrigger(JobDetail newJob, OperableTrigger newTrigger)
public void storeJobAndTrigger(JobDetail newJob, OperableTrigger newTrigger) throws JobPersistenceException {
    storeJob(newJob, false);
    storeTrigger(newTrigger, false);
}

  • RAMJobStore.storeJob(JobDetail newJob, boolean replaceExisting)
public void storeJob(JobDetail newJob,
            boolean replaceExisting) throws ObjectAlreadyExistsException {
        JobWrapper jw = new JobWrapper((JobDetail)newJob.clone());

        boolean repl = false;

        synchronized (lock) {
            if (jobsByKey.get(jw.key) != null) {
                if (!replaceExisting) {
                    throw new ObjectAlreadyExistsException(newJob);
                }
                repl = true;
            }

            if (!repl) {
                // get job group
                HashMap<JobKey, JobWrapper> grpMap = jobsByGroup.get(newJob.getKey().getGroup());
                if (grpMap == null) {
                    grpMap = new HashMap<JobKey, JobWrapper>(100);
                    jobsByGroup.put(newJob.getKey().getGroup(), grpMap);
                }
                // add to jobs by group
                grpMap.put(newJob.getKey(), jw);
                // add to jobs by FQN map
                jobsByKey.put(jw.key, jw);
            } else {
                // update job detail
                JobWrapper orig = jobsByKey.get(jw.key);
                orig.jobDetail = jw.jobDetail; // already cloned
            }
        }
    }

storeJob(newJob, false)和storeTrigger(newTrigger, false)n内容差不多,都是按key和按group保存Job或者Trigger信息

现在,JobDetail和Trigger已经添加到Scheduler里了。

发布了10 篇原创文章 · 获赞 1 · 访问量 6827

猜你喜欢

转载自blog.csdn.net/jakekong/article/details/104901810
今日推荐