Quartz源码分析(二)
2015-08-14 19:07
351 查看
原文地址:http://smurfs.iteye.com/blog/1157692
Quartz框架执行的任务需要写在一个实现Job接口的类中,在实现类中的execute(JobExecutionContext
context)中执行相关的操作,通过实现Job接口来使你的Java 组件可以很简单的被scheduler执行,下面是job接口:
如上,你会看到job触发器出发时,job的execute方法会被执行。那么,scheduler的job是通过何种方式创建和执行的呢。先来看看job的部署,job是通过jobdetail scheduler到框架中去的,然后通过getJobClass()方法获取到job实现类的class字节码的,通过jobFactory的newJob()方法反射出Java 的具体实例,然后在JobRunShell线程对象的run方法中执行。
1、 先看看jobdetail的创建,在quartz2.2.1中,jobdetail是通过jobbuilder创建
2、 创建好jobdetail后,scheduler通过线程类JobRunShell来执行Job。
通过initialize方法中调用JobFactory的newJob()创建Job实例。
Quartz框架执行的任务需要写在一个实现Job接口的类中,在实现类中的execute(JobExecutionContext
context)中执行相关的操作,通过实现Job接口来使你的Java 组件可以很简单的被scheduler执行,下面是job接口:
/** * <p> * Called by the <code>{@link Scheduler}</code> when a <code>{@link Trigger}</code> * fires that is associated with the <code>Job</code>. * </p> * * <p> * The implementation may wish to set a * {@link JobExecutionContext#setResult(Object) result} object on the * {@link JobExecutionContext} before this method exits. The result itself * is meaningless to Quartz, but may be informative to * <code>{@link JobListener}s</code> or * <code>{@link TriggerListener}s</code> that are watching the job's * execution. * </p> * * @throws JobExecutionException * if there is an exception while executing the job. */ void execute(JobExecutionContext context) throws JobExecutionException;
如上,你会看到job触发器出发时,job的execute方法会被执行。那么,scheduler的job是通过何种方式创建和执行的呢。先来看看job的部署,job是通过jobdetail scheduler到框架中去的,然后通过getJobClass()方法获取到job实现类的class字节码的,通过jobFactory的newJob()方法反射出Java 的具体实例,然后在JobRunShell线程对象的run方法中执行。
1、 先看看jobdetail的创建,在quartz2.2.1中,jobdetail是通过jobbuilder创建
/** * Produce the <code>JobDetail</code> instance defined by this * <code>JobBuilder</code>. * * @return the defined JobDetail. */ public JobDetail build() { JobDetailImpl job = new JobDetailImpl(); job.setJobClass(jobClass); job.setDescription(description); if(key == null) key = new JobKey(Key.createUniqueName(null), null); job.setKey(key); job.setDurability(durability); job.setRequestsRecovery(shouldRecover); if(!jobDataMap.isEmpty()) job.setJobDataMap(jobDataMap); return job; }Jobbuilder通过静态方法newjob()不同重载来创建Jobbuilder,通过withIdentity()重载设置参数,如下:
/** * Create a JobBuilder with which to define a <code>JobDetail</code>, * and set the class name of the <code>Job</code> to be executed. * * @return a new JobBuilder */ public static JobBuilder newJob(Class <? extends Job> jobClass) { JobBuilder b = new JobBuilder(); b.ofType(jobClass); return b; }
/** * Use a <code>JobKey</code> with the given name and default group to * identify the JobDetail. * * <p>If none of the 'withIdentity' methods are set on the JobBuilder, * then a random, unique JobKey will be generated.</p> * * @param name the name element for the Job's JobKey * @return the updated JobBuilder * @see JobKey * @see JobDetail#getKey() */ public JobBuilder withIdentity(String name) { key = new JobKey(name, null); return this; }
2、 创建好jobdetail后,scheduler通过线程类JobRunShell来执行Job。
通过initialize方法中调用JobFactory的newJob()创建Job实例。
public void initialize(QuartzScheduler sched) throws SchedulerException { this.qs = sched; Job job = null; JobDetail jobDetail = firedTriggerBundle.getJobDetail(); try { job = sched.getJobFactory().newJob(firedTriggerBundle, scheduler); } catch (SchedulerException se) { sched.notifySchedulerListenersError( "An error occured instantiating job to be executed. job= '" + jobDetail.getKey() + "'", se); throw se; } catch (Throwable ncdfe) { // such as NoClassDefFoundError SchedulerException se = new SchedulerException( "Problem instantiating class '" + jobDetail.getJobClass().getName() + "' - ", ncdfe); sched.notifySchedulerListenersError( "An error occured instantiating job to be executed. job= '" + jobDetail.getKey() + "'", se); throw se; } this.jec = new JobExecutionContextImpl(scheduler, firedTriggerBundle, job); }JobFactory的newJob()方法通过反射使用默认无参数的构造方法实现job实例创建,如下:
public Job newJob(TriggerFiredBundle bundle, Scheduler Scheduler) throws SchedulerException { JobDetail jobDetail = bundle.getJobDetail(); Class<? extends Job> jobClass = jobDetail.getJobClass(); try { if(log.isDebugEnabled()) { log.debug( "Producing instance of Job '" + jobDetail.getKey() + "', class=" + jobClass.getName()); } return jobClass.newInstance(); } catch (Exception e) { SchedulerException se = new SchedulerException( "Problem instantiating class '" + jobDetail.getJobClass().getName() + "'", e); throw se; } }Job的执行很简单,直接调用execute方法即可:
public QuartzScheduler(QuartzSchedulerResources resources, long idleWaitTime, @Deprecated long dbRetryInterval) throws SchedulerException { this.resources = resources; if (resources.getJobStore() instanceof JobListener) { addInternalJobListener((JobListener)resources.getJobStore()); } this.schedThread = new QuartzSchedulerThread(this, resources); ThreadExecutor schedThreadExecutor = resources.getThreadExecutor(); schedThreadExecutor.execute(this.schedThread); if (idleWaitTime > 0) { this.schedThread.setIdleWaitTime(idleWaitTime); } jobMgr = new ExecutingJobsManager(); addInternalJobListener(jobMgr); errLogger = new ErrorLogger(); addInternalSchedulerListener(errLogger); signaler = new SchedulerSignalerImpl(this, this.schedThread); if(shouldRunUpdateCheck()) updateTimer = scheduleUpdateCheck(); else updateTimer = null; getLog().info("Quartz Scheduler v." + getVersion() + " created."); }Job的实现和执行很简单, 主要是业务逻辑,以下简单的把类之间的关系整理下:
相关文章推荐
- Python学习笔记23:Django构建一个简单的博客网站(一个)
- 九度oj 1030
- hdu 1171 Big Event in HDU 多重背包问题
- Android常用的一些make命令
- VC和gcc在保证功能static对线程安全的差异变量
- Ampzz 2011 Cross Spider 计算几何
- java:可变类StringBuffer与不可变类String
- VisualSVN5.0.1补丁原创发布
- 拓扑排序模板-优先队列 hdu 1285 确定比赛名次
- POJ 1181 大整数是否为素数以及求大整数的质因数-数论-(Miller_rabin+Pollard_rho)
- 最小生成树prim算法实现
- HDU 1232 畅通工程
- 九度 Online Judge 算法 刷题 题目1064:反序数
- ssh 使用密钥与登录进行远程cp
- poj 1458
- 关于Qt5 QML中Canvas画布叠加区域为透明时,如何传递鼠标事件到下层画布。
- JPA学习笔记(6)——EntityTransaction
- Bugzilla设置
- java获取Json和http状态码
- The Minimum Length - HUST 1010(求最小循环节)