Quartz(三)原理及源码分析
quartz配置文件中可以通过以下两种配置读取方式
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore(从内存中读取定时任务)
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX(从数据库中读取定时任务)
以JobStoreTX为例,它最核心的组成部分是Scheduler、Trigger、JobDetail,然后给Scheduler配置个线程QuartzSchedulerThread,此线程在服务器启动时初始化Scheduler时启动,等待Scheduler start,然后从JobStore里拿到最近要触发的Trigger。
Scheduler:接口定义了对定时任务主要操作方法。
Trigger:定时器定义了任务执行时间。
JobDetail:定时任务一个JobDetail可以配置多个Trigger,主要定义了定时执行的类,方法,参数等信息。
任务定时执行:在服务器启动以后,每隔几秒至几十秒就会轮询StdJDBCDelegate类中selectTriggerToAcquire方法,执行sql查询qrtz_triggers表中NEXT_FIRE_TIME(下次触发时间)字段符合当前时间段并且TRIGGER_STATE状态为WAITING(等待中),符合此条件的Trigger查询出来,关联jobDetail来得到配置参数,调用配置好的业务方法。
if(updateJobData) {ps = conn.prepareStatement(rtp(UPDATE_TRIGGER));} else {ps = conn.prepareStatement(rtp(UPDATE_TRIGGER_SKIP_DATA));}ps.setString(1, trigger.getJobName());ps.setString(2, trigger.getJobGroup());setBoolean(ps, 3, trigger.isVolatile());ps.setString(4, trigger.getDescription());long nextFireTime = -1;if (trigger.getNextFireTime() != null) {nextFireTime = trigger.getNextFireTime().getTime();}ps.setBigDecimal(5, new BigDecimal(String.valueOf(nextFireTime)));long prevFireTime = -1;if (trigger.getPreviousFireTime() != null) {prevFireTime = trigger.getPreviousFireTime().getTime();}ps.setBigDecimal(6, new BigDecimal(String.valueOf(prevFireTime)));ps.setString(7, state);if (trigger instanceof SimpleTrigger && ((SimpleTrigger)trigger).hasAdditionalProperties() == false ) {// updateSimpleTrigger(conn, (SimpleTrigger)trigger);ps.setString(8, TTYPE_SIMPLE);} else if (trigger instanceof CronTrigger && ((CronTrigger)trigger).hasAdditionalProperties() == false ) {// updateCronTrigger(conn, (CronTrigger)trigger);ps.setString(8, TTYPE_CRON);} else {// updateBlobTrigger(conn, trigger);ps.setString(8, TTYPE_BLOB);}ps.setBigDecimal(9, new BigDecimal(String.valueOf(trigger.getStartTime().getTime())));//代码略......