quartzソース1-spring構成
21738 ワード
一つの任務job
1.1 jobDetail関連
1.1.1 JobDetailFactoryBean
jobインタフェースの実行タスククラスを継承する方法を指定してjobdetailを構成し、タスク実行時にjobインタフェースを介して実行タスクを呼び出す
ツールバーの
説明
String name;
jobDetail名
String group;
jobDetailグループ
Class> jobClass;
jobDetailが実行するタスククラス
JobDataMap jobDataMap
jobDetailの永続化データ
boolean durability
永続化するかどうか
boolean requestsRecovery
jobDetailがリカバリ可能かどうか
String description
jobDetailの説明
String beanName
jobDetailのbean名
ApplicationContext applicationContext;
bean容器
String applicationContextJobDataKey;
job呼び出しパラメータのbeanコンテナのkey値
JobDetail jobDetail;
前述のプロパティ初期化されたJobDetailImplの実際のオブジェクト
1.1.2 MethodInvokingJobDetailFactoryBeanターゲットクラスを指定し、タスク実行方法によりjobdetailを構成し、タスク実行時に反射呼び出しによりタスク を実行する. 初期化タスク実行のjobインタフェース実装クラスjobClass を初期化する.
1.1.2.1タスクの実行 から継承されます. QuartzJobBean担当属性注入 タスク実行、反射呼び出しターゲットメソッドオブジェクト
1.2 jobFactory
1.2.1 AdaptableJobFactoryで構成されたjobクラスで、runnableの場合はエージェントが作成されます. で構成されたjobクラスは、jobインタフェース実装クラスは に直接戻る.その他のタイプは要求に合致せず、投げ異常
1.2.2 SpringBeanJobFactory extends AdaptableJobFactory非QuartzJobBeanクラスはいくつかの属性注入の処理 を行う. ignoredUnknownProperties構成は、jobクラスで書き込み不可であり、注入する必要がない属性を指定します.
1.3 job
1.3.1 DelegatingJob
エージェントrunnableのタスククラス
1.3.2 QuartzJobBean属性注入を行う
にフリップフロップtrigger
2.1 SimpleTriggerFactoryBeanサイクルトリガで、サイクル時間とトリガ回数を指定できます.
2.1.1属性
ツールバーの
説明
String name;
trigger名
String group;
triggerパケット
JobDetail jobDetail;
trigger所属job情報
JobDataMap jobDataMap
job永続化データ
Date startTime;
開始時間
long startDelay;
どのくらい遅延してトリガーを開始しますか?
long repeatInterval;
繰り返しトリガの周期間隔
int repeatCount = -1;
繰り返し回数
int priority;
スケジューリング優先度
int misfireInstruction;
エラーポリシー
String description
説明情報
String beanName;
現在のbean名
SimpleTrigger simpleTrigger;
前述のプロパティを使用してSimpleTriggerImplを初期化
2.1.2インタフェースの説明
2.2 CronTriggerFactoryBeanタイミングトリガ、cronルールに従ってタイミングトリガ.その他の構成は、周期トリガと同じ ツールバーの
説明
String cronExpression
タイミングルール
CronTrigger cronTrigger;
タイミングトリガ、CronTriggerImpl実装クラス
3スケジューリングクラスSchedulerFactoryBean を表す. が呼び出されることを示す. が呼び出されることを示す.
3.1 afterPropertiesSet()
3.1.1スケジューラ工場の初期化ユーザ構成に従ってスケジューラ工場 を初期化する.
3.1.2スケジューラの作成初期化スレッドのクラスローダ synchronizedロック同時作成スケジューラ を回避スケジューラ の取得または作成
3.1.2.1 StdSchedulerFactory.instantiate()ユーザ構成変換 リモートスケジューラエージェント初期化 カスタムクラスローダインスタンス化 JMXリモートスケジューラ初期化 job工場類実例化 idジェネレータ を実例化する.スレッドプールインスタンス化 データ永続化インスタンス化 データベース接続プールインスタンス化 プラグイン初期化 listener初期化 jobスレッドアクチュエータ初期化 jobコンテナファクトリ初期化 を実行上記スケジューラ関連リソース を組み立てる.初期化スケジューラ 初期化スケジューラエージェント 各リソース初期化 スケジューリング初期化 を参照してください.
3.1.3スケジューラコンテキストの初期化 bean容器 ユーザ構成のschedulerContextMap スケジューラを更新するjob工場 3.1.4ユーザー構成のlistenerの登録スケジューリングフローリスニングコールバック jobステータスリスニングコールバック triggerステータスリスニングコールバック
3.1.5ユーザー構成のjobとtriggerを登録するトランザクション方式統合追加構成jobとtrigger 単独xml構成jobとtriggerの登録 job を追加 trigger を追加
3.2 start()は遅延起動をサポートし、スケジューリングスレッドによってスケジューリング を遅延する.スケジューラstartインタフェース呼び出し
1.1 jobDetail関連
1.1.1 JobDetailFactoryBean
jobインタフェースの実行タスククラスを継承する方法を指定してjobdetailを構成し、タスク実行時にjobインタフェースを介して実行タスクを呼び出す
ツールバーの
説明
String name;
jobDetail名
String group;
jobDetailグループ
Class> jobClass;
jobDetailが実行するタスククラス
JobDataMap jobDataMap
jobDetailの永続化データ
boolean durability
永続化するかどうか
boolean requestsRecovery
jobDetailがリカバリ可能かどうか
String description
jobDetailの説明
String beanName
jobDetailのbean名
ApplicationContext applicationContext;
bean容器
String applicationContextJobDataKey;
job呼び出しパラメータのbeanコンテナのkey値
JobDetail jobDetail;
前述のプロパティ初期化されたJobDetailImplの実際のオブジェクト
1.1.2 MethodInvokingJobDetailFactoryBean
prepare()
ターゲットクラス、メソッド、パラメータに基づいて反射メソッドオブジェクトを初期化します.jdi.getJobDataMap().put("methodInvoker", this);
タスク実行時にjobClassのmethodInvoker属性public void afterPropertiesSet() throws ClassNotFoundException, NoSuchMethodException {
this.prepare();
String name = this.name != null?this.name:this.beanName;
Class> jobClass = this.concurrent?MethodInvokingJobDetailFactoryBean.MethodInvokingJob.class:MethodInvokingJobDetailFactoryBean.StatefulMethodInvokingJob.class;
JobDetailImpl jdi = new JobDetailImpl();
jdi.setName(name);
jdi.setGroup(this.group);
jdi.setJobClass(jobClass);
jdi.setDurability(true);
jdi.getJobDataMap().put("methodInvoker", this);
this.jobDetail = jdi;
this.postProcessJobDetail(this.jobDetail);
}
public void prepare() throws ClassNotFoundException, NoSuchMethodException {
String targetMethod;
if(this.staticMethod != null) {
int lastDotIndex = this.staticMethod.lastIndexOf(46);
if(lastDotIndex == -1 || lastDotIndex == this.staticMethod.length()) {
throw new IllegalArgumentException("staticMethod must be a fully qualified class plus method name: e.g. 'example.MyExampleClass.myExampleMethod'");
}
targetMethod = this.staticMethod.substring(0, lastDotIndex);
String methodName = this.staticMethod.substring(lastDotIndex + 1);
this.targetClass = this.resolveClassName(targetMethod);
this.targetMethod = methodName;
}
Class> targetClass = this.getTargetClass();
targetMethod = this.getTargetMethod();
Assert.notNull(targetClass, "Either 'targetClass' or 'targetObject' is required");
Assert.notNull(targetMethod, "Property 'targetMethod' is required");
Object[] arguments = this.getArguments();
Class>[] argTypes = new Class[arguments.length];
for(int i = 0; i < arguments.length; ++i) {
argTypes[i] = arguments[i] != null?arguments[i].getClass():Object.class;
}
try {
this.methodObject = targetClass.getMethod(targetMethod, argTypes);
} catch (NoSuchMethodException var6) {
this.methodObject = this.findMatchingMethod();
if(this.methodObject == null) {
throw var6;
}
}
}
1.1.2.1タスクの実行
public static class MethodInvokingJob extends QuartzJobBean
タスクはQuartzJobBean private MethodInvoker methodInvoker;
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
context.setResult(this.methodInvoker.invoke());
}
public Object invoke() throws InvocationTargetException, IllegalAccessException {
Object targetObject = this.getTargetObject();
Method preparedMethod = this.getPreparedMethod();
if(targetObject == null && !Modifier.isStatic(preparedMethod.getModifiers())) {
throw new IllegalArgumentException("Target method must not be non-static without a target");
} else {
ReflectionUtils.makeAccessible(preparedMethod);
return preparedMethod.invoke(targetObject, this.getArguments());
}
}
1.2 jobFactory
1.2.1 AdaptableJobFactory
protected Job adaptJob(Object jobObject) throws Exception {
if(jobObject instanceof Job) {
return (Job)jobObject;
} else if(jobObject instanceof Runnable) {
return new DelegatingJob((Runnable)jobObject);
} else {
throw new IllegalArgumentException("Unable to execute job class [" + jobObject.getClass().getName() + "]: only [org.quartz.Job] and [java.lang.Runnable] supported.");
}
}
1.2.2 SpringBeanJobFactory extends AdaptableJobFactory
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object job = super.createJobInstance(bundle);
if(this.isEligibleForPropertyPopulation(job)) {
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(job);
MutablePropertyValues pvs = new MutablePropertyValues();
if(this.schedulerContext != null) {
pvs.addPropertyValues(this.schedulerContext);
}
pvs.addPropertyValues(bundle.getJobDetail().getJobDataMap());
pvs.addPropertyValues(bundle.getTrigger().getJobDataMap());
if(this.ignoredUnknownProperties != null) {
String[] var5 = this.ignoredUnknownProperties;
int var6 = var5.length;
for(int var7 = 0; var7 < var6; ++var7) {
String propName = var5[var7];
if(pvs.contains(propName) && !bw.isWritableProperty(propName)) {
pvs.removePropertyValue(propName);
}
}
bw.setPropertyValues(pvs);
} else {
bw.setPropertyValues(pvs, true);
}
}
return job;
}
1.3 job
1.3.1 DelegatingJob
エージェントrunnableのタスククラス
1.3.2 QuartzJobBean
public final void execute(JobExecutionContext context) throws JobExecutionException {
try {
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.addPropertyValues(context.getScheduler().getContext());
pvs.addPropertyValues(context.getMergedJobDataMap());
bw.setPropertyValues(pvs, true);
} catch (SchedulerException var4) {
throw new JobExecutionException(var4);
}
this.executeInternal(context);
}
にフリップフロップtrigger
2.1 SimpleTriggerFactoryBean
2.1.1属性
ツールバーの
説明
String name;
trigger名
String group;
triggerパケット
JobDetail jobDetail;
trigger所属job情報
JobDataMap jobDataMap
job永続化データ
Date startTime;
開始時間
long startDelay;
どのくらい遅延してトリガーを開始しますか?
long repeatInterval;
繰り返しトリガの周期間隔
int repeatCount = -1;
繰り返し回数
int priority;
スケジューリング優先度
int misfireInstruction;
エラーポリシー
String description
説明情報
String beanName;
現在のbean名
SimpleTrigger simpleTrigger;
前述のプロパティを使用してSimpleTriggerImplを初期化
2.1.2インタフェースの説明
public void afterPropertiesSet()
bean初期化完了後に呼び出され、現在のbeanが実際に返されたオブジェクトとしてSimpleTriggerオブジェクトが初期化されます. public SimpleTrigger getObject() {
return this.simpleTrigger;
}
public Class> getObjectType() {
return SimpleTrigger.class;
}
2.2 CronTriggerFactoryBean
説明
String cronExpression
タイミングルール
CronTrigger cronTrigger;
タイミングトリガ、CronTriggerImpl実装クラス
3スケジューリングクラスSchedulerFactoryBean
FactoryBean
インタフェースは工場bean InitializingBean
インタフェースは、属性初期化が完了するとafterPropertiesSet()
SmartLifecycle
インタフェースは、すべてのbean初期化が完了するとstart()
3.1 afterPropertiesSet()
3.1.1スケジューラ工場の初期化
SchedulerFactory schedulerFactory = (SchedulerFactory)BeanUtils.instantiateClass(this.schedulerFactoryClass);
this.initSchedulerFactory(schedulerFactory);
((StdSchedulerFactory)schedulerFactory).initialize(mergedProps);
3.1.2スケジューラの作成
SchedulerRepository repository
キャッシュ作成スケジューラprotected Scheduler createScheduler(SchedulerFactory schedulerFactory, String schedulerName) throws SchedulerException {
Thread currentThread = Thread.currentThread();
ClassLoader threadContextClassLoader = currentThread.getContextClassLoader();
boolean overrideClassLoader = this.resourceLoader != null && !this.resourceLoader.getClassLoader().equals(threadContextClassLoader);
if(overrideClassLoader) {
currentThread.setContextClassLoader(this.resourceLoader.getClassLoader());
}
Scheduler var10;
try {
SchedulerRepository repository = SchedulerRepository.getInstance();
synchronized(repository) {
Scheduler existingScheduler = schedulerName != null?repository.lookup(schedulerName):null;
Scheduler newScheduler = schedulerFactory.getScheduler();
if(newScheduler == existingScheduler) {
throw new IllegalStateException("Active Scheduler of name '" + schedulerName + "' already registered in Quartz SchedulerRepository. Cannot create a new Spring-managed Scheduler of the same name!");
}
if(!this.exposeSchedulerInRepository) {
SchedulerRepository.getInstance().remove(newScheduler.getSchedulerName());
}
var10 = newScheduler;
}
} finally {
if(overrideClassLoader) {
currentThread.setContextClassLoader(threadContextClassLoader);
}
}
return var10;
}
public Scheduler getScheduler() throws SchedulerException {
if (cfg == null) {
initialize();
}
SchedulerRepository schedRep = SchedulerRepository.getInstance();
Scheduler sched = schedRep.lookup(getSchedulerName());
if (sched != null) {
if (sched.isShutdown()) {
schedRep.remove(getSchedulerName());
} else {
return sched;
}
}
sched = instantiate();
return sched;
}
3.1.2.1 StdSchedulerFactory.instantiate()
RemoteScheduler
loadHelper = (ClassLoadHelper) loadClass(classLoadHelperClass) .newInstance();
jobFactory = (JobFactory) loadHelper.loadClass(jobFactoryClass) .newInstance();
instanceIdGenerator = (InstanceIdGenerator) loadHelper.loadClass(instanceIdGeneratorClass) .newInstance();
ThreadPool
JobStore
JobRunShellFactory jrsf = null; // Create correct run-shell factory...
if (userTXLocation != null) {
UserTransactionHelper.setUserTxLocation(userTXLocation);
}
if (wrapJobInTx) {
jrsf = new JTAJobRunShellFactory();
} else {
jrsf = new JTAAnnotationAwareJobRunShellFactory();
}
QuartzSchedulerResources
QuartzSchedulerResources rsrcs = new QuartzSchedulerResources();
rsrcs.setName(schedName);
rsrcs.setThreadName(threadName);
rsrcs.setInstanceId(schedInstId);
rsrcs.setJobRunShellFactory(jrsf);
rsrcs.setMakeSchedulerThreadDaemon(makeSchedulerThreadDaemon);
rsrcs.setThreadsInheritInitializersClassLoadContext(threadsInheritInitalizersClassLoader);
rsrcs.setBatchTimeWindow(batchTimeWindow);
rsrcs.setMaxBatchSize(maxBatchSize);
rsrcs.setInterruptJobsOnShutdown(interruptJobsOnShutdown);
rsrcs.setInterruptJobsOnShutdownWithWait(interruptJobsOnShutdownWithWait);
rsrcs.setJMXExport(jmxExport);
rsrcs.setJMXObjectName(jmxObjectName);
if (managementRESTServiceEnabled) {
ManagementRESTServiceConfiguration managementRESTServiceConfiguration = new ManagementRESTServiceConfiguration();
managementRESTServiceConfiguration.setBind(managementRESTServiceHostAndPort);
managementRESTServiceConfiguration.setEnabled(managementRESTServiceEnabled);
rsrcs.setManagementRESTServiceConfiguration(managementRESTServiceConfiguration);
}
if (rmiExport) {
rsrcs.setRMIRegistryHost(rmiHost);
rsrcs.setRMIRegistryPort(rmiPort);
rsrcs.setRMIServerPort(rmiServerPort);
rsrcs.setRMICreateRegistryStrategy(rmiCreateRegistry);
rsrcs.setRMIBindName(rmiBindName);
}
SchedulerDetailsSetter.setDetails(tp, schedName, schedInstId);
rsrcs.setThreadExecutor(threadExecutor);
threadExecutor.initialize();
rsrcs.setThreadPool(tp);
if(tp instanceof SimpleThreadPool) {
if(threadsInheritInitalizersClassLoader)
((SimpleThreadPool)tp).setThreadsInheritContextClassLoaderOfInitializingThread(threadsInheritInitalizersClassLoader);
}
tp.initialize();
tpInited = true;
rsrcs.setJobStore(js);
// add plugins
for (int i = 0; i < plugins.length; i++) {
rsrcs.addSchedulerPlugin(plugins[i]);
}
qs = new QuartzScheduler(rsrcs, idleWaitTime, dbFailureRetry);
Scheduler scheduler = new StdScheduler(qs);
qs.initialize();
詳細は、後続の文書3.1.3スケジューラコンテキストの初期化
protected void registerListeners() throws SchedulerException {
ListenerManager listenerManager = this.getScheduler().getListenerManager();
int var3;
int var4;
if(this.schedulerListeners != null) {
SchedulerListener[] var2 = this.schedulerListeners;
var3 = var2.length;
for(var4 = 0; var4 < var3; ++var4) {
SchedulerListener listener = var2[var4];
listenerManager.addSchedulerListener(listener);
}
}
if(this.globalJobListeners != null) {
JobListener[] var6 = this.globalJobListeners;
var3 = var6.length;
for(var4 = 0; var4 < var3; ++var4) {
JobListener listener = var6[var4];
listenerManager.addJobListener(listener);
}
}
if(this.globalTriggerListeners != null) {
TriggerListener[] var7 = this.globalTriggerListeners;
var3 = var7.length;
for(var4 = 0; var4 < var3; ++var4) {
TriggerListener listener = var7[var4];
listenerManager.addTriggerListener(listener);
}
}
}
3.1.5ユーザー構成のjobとtriggerを登録する
this.getScheduler().addJob(jobDetail, true);
this.getScheduler().rescheduleJob(trigger.getKey(), trigger);
this.getScheduler().scheduleJob(trigger);
this.getScheduler().scheduleJob(jobDetail, trigger);
protected void registerJobsAndTriggers() throws SchedulerException {
TransactionStatus transactionStatus = null;
if(this.transactionManager != null) {
transactionStatus = this.transactionManager.getTransaction(new DefaultTransactionDefinition());
}
try {
if(this.jobSchedulingDataLocations != null) {
ClassLoadHelper clh = new ResourceLoaderClassLoadHelper(this.resourceLoader);
clh.initialize();
XMLSchedulingDataProcessor dataProcessor = new XMLSchedulingDataProcessor(clh);
String[] var4 = this.jobSchedulingDataLocations;
int var5 = var4.length;
for(int var6 = 0; var6 < var5; ++var6) {
String location = var4[var6];
dataProcessor.processFileAndScheduleJobs(location, this.getScheduler());
}
}
Iterator var10;
if(this.jobDetails != null) {
var10 = this.jobDetails.iterator();
while(var10.hasNext()) {
JobDetail jobDetail = (JobDetail)var10.next();
this.addJobToScheduler(jobDetail);
}
} else {
this.jobDetails = new LinkedList();
}
if(this.calendars != null) {
var10 = this.calendars.keySet().iterator();
while(var10.hasNext()) {
String calendarName = (String)var10.next();
Calendar calendar = (Calendar)this.calendars.get(calendarName);
this.getScheduler().addCalendar(calendarName, calendar, true, true);
}
}
if(this.triggers != null) {
var10 = this.triggers.iterator();
while(var10.hasNext()) {
Trigger trigger = (Trigger)var10.next();
this.addTriggerToScheduler(trigger);
}
}
} catch (Throwable var9) {
if(transactionStatus != null) {
try {
this.transactionManager.rollback(transactionStatus);
} catch (TransactionException var8) {
this.logger.error("Job registration exception overridden by rollback exception", var9);
throw var8;
}
}
if(var9 instanceof SchedulerException) {
throw (SchedulerException)var9;
}
if(var9 instanceof Exception) {
throw new SchedulerException("Registration of jobs and triggers failed: " + var9.getMessage(), var9);
}
throw new SchedulerException("Registration of jobs and triggers failed: " + var9.getMessage());
}
if(transactionStatus != null) {
this.transactionManager.commit(transactionStatus);
}
}
3.2 start()
scheduler.start();
protected void startScheduler(final Scheduler scheduler, final int startupDelay) throws SchedulerException {
if(startupDelay <= 0) {
this.logger.info("Starting Quartz Scheduler now");
scheduler.start();
} else {
if(this.logger.isInfoEnabled()) {
this.logger.info("Will start Quartz Scheduler [" + scheduler.getSchedulerName() + "] in " + startupDelay + " seconds");
}
Thread schedulerThread = new Thread() {
public void run() {
try {
Thread.sleep((long)(startupDelay * 1000));
} catch (InterruptedException var3) {
;
}
if(SchedulerFactoryBean.this.logger.isInfoEnabled()) {
SchedulerFactoryBean.this.logger.info("Starting Quartz Scheduler now, after delay of " + startupDelay + " seconds");
}
try {
scheduler.start();
} catch (SchedulerException var2) {
throw new SchedulingException("Could not start Quartz Scheduler after delay", var2);
}
}
};
schedulerThread.setName("Quartz Scheduler [" + scheduler.getSchedulerName() + "]");
schedulerThread.setDaemon(true);
schedulerThread.start();
}
}