探究 Spring 的定時任務配置

探究 Spring 的定時任務配置

作者 | 郭朝興

最近在項目開發中進行了一些Spring定時任務的開發工作,在開發過程中對Spring定時任務的配置方式進行了一些研究,現在對各種配置方式進行一個總結。Scheduled是Spring支持的定時任務配置方式,可以用註解或者配置文件的方式進行配置。

Quartz是一個強大的企業級任務調度框架,Spring中繼承並簡化了Quartz,它是一個開源的由OpenSymphony維護的項目,開發者能夠在Java EE,或單獨的Java SE應用中使用它。無論是簡單的任務調度,還是複雜的企業級應用,Quartz都能夠很好地勝任。

Quartz支持CronTriggerBean,SimpleTriggerBean兩種模式,CronTriggerBean比 SimpleTriggerBean功能更強大,它能夠控制任務執行的精確時間,比如,早上九點半需要執行某QuartzJobBean中給定的任務。

以下對不同的配置方式分別進行介紹。

探究 Spring 的定时任务配置

通Scheduled註解或者xml配置的方式添加定時任務

ref 是定時任務的類在 Spring中的beanName,method是要執行的方法,fixed-delay 是上一個調用完成後,再次調用的延時,fixed-rate 是 上一個調用開始後,再次調用的延時(不用等待上一次調用完成),cron 是表達式,表示在什麼時候進行任務調度。

<code><scheduled-tasks>
<scheduled>
/<scheduled-tasks>
<scheduler>/<code>

也可以採用註解的方式,在需要配置為定時任務的方法上添加@Scheduled(cron = "0 0 3 * * ?"),cron為定時任務表達式,cron表達式支持非常豐富的配置規則。

<code>@Component(“taskJob”) 
public class TaskJob { k
@Scheduled(cron = "0 0 3 * * ?")
public void job1 {
System.out.println(“任務進行中。。。”);
}
}
/<code>

配置任務執行的線程池信息。task:scheduler用來配置任務調度線程池大小,調度線程在被調度任務完成前不會空閒;task:executor用來配置任務執行器的具體參數,pool-size 可以指定執行線程池的初始大小、最大大小,queue-capacity配置等待執行任務的隊列容量,reject-policy當等待隊列爆了時的策略,分為丟棄、有任務執行器直接執行等方式。

<code> <executor>
<scheduler>
<annotation-driven>/<code>
探究 Spring 的定时任务配置

CronTrigger配置方式

CronTrigger 支持比simpleTrigger更具體的調度,CronTrigger支持類似日曆的重複間隔。CronTrigger 由MethodInvokingJobDetailFactoryBean、CronTriggerFactoryBean兩個類支持。

MethodInvokingJobDetailFactoryBean配置需要定時執行的任務類和方法,targetObject為執行定時任務的bean,targetMethod為執行定時任務的bean中的方法。CronTriggerFactoryBean為定時任務的觸發器,用來配置定時任務執行的時間表達式。

<code> <bean>
<property>

<property>
/<bean>
<bean>class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property>
<property>
/<bean>/<code>
探究 Spring 的定时任务配置

SimpleTigger配置方式

當需要在規定的時間執行一次或者以一定的時間間隔重複出發執行job時,SimpleTrigger 就可以滿足要求。SimpleTrigger的屬性有:開始時間、結束時間、重複次數、重複時間間隔。

如下示例:首先創建需要執行定時任務的bean,名字為quartzBean。然後配置該bean需要定時執行的方法。Concurrent參數用來配置是否同步執行。如果配置為true,則任務執行時,只有上次執行完成後,才可以進入下一次執行。

SimpleTriggerFactoryBean配置了觸發器執行的策略,開始執行的延遲時間及執行的時間間隔。SchedulerFactoryBean用來管理任務計劃,是任務的總的管理類。將lazy-init='false'那麼容器啟動就會執行調度程序。

<code> <bean>
<property>
/<bean>

<bean>
<property>
<property>
<property>
/<bean>
<bean>class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property>
<property>
<property>300000">/<property>
/<bean>

<bean>
<property>
<list>

/<list>
/<property>
/<bean>/<code>
探究 Spring 的定时任务配置

SimpleTrigger與CronTrigger高級應用場景

針對需要將定時任務配置為根據用戶的實際運行需要,動態調整任務執行的計劃,並準實時生效的情況。可以採用配置頁面的方式由用戶選擇任務的執行計劃,然後將各個任務的執行計劃添加到數據庫中。週期性的從數據庫中讀取定時任務信息,添加、更新、刪除定時任務線程。

當Spring 啟動時,就會創建schedulerManager作為總的管理類,由schedulerManager來管理所有的任務,schedulerManager在後臺每隔一定的時間(配置)執行一次,來監測數據庫中需要創建和更新的定時任務。

schedulerManager讀取數據庫中的定時任務(任務類、任務方法、執行時間),判斷定時觸發器中是否存在該任務,如果存在,比較數據庫中的任務表達式(cron)是否與當前定時器中的時間一致,如果不一致,更新當前任務時間表達式。如果不存在該任務,將任務加入到定時器中。

探究 Spring 的定时任务配置

此種方式創建任務也是基於MethodInvokingJobDetailFactoryBean,CronTriggerFactoryBean 兩個類,但是創建方式為通過代碼進行實例化,可以根據實際需要動態的創建,靈活性更加強,使用起來也更加的方便,創建任務有2個步驟,具體如下:

(1)實例化任務

首先實例化MethodInvokingJobDetailFactoryBean,MethodInvokingJobDetailFactoryBean是spring自帶的,並將數據庫中配置的job相關信息添加到mijdfb,然後調用afterPropertiesSet方法,這個方法會實例化一個JobDetailImpl,並將相應的信息添加到JobDetailImpl中。該過程實例化了需要定時調度的類和方法,並可以向類和方法中傳入制定的參數,使用配置文件的方式無法達到對應的效果。

<code>MethodInvokingJobDetailFactoryBean mijdfb=new MethodInvokingJobDetailFactoryBean;
mijdfb.setName(qm.getEnvId);
mijdfb.setTargetObject(beanFactory.getBean("service",Mservice.class));
mijdfb.setTargetMethod("runTask");
mijdfb.setConcurrent(false);
TestEnvDomain params = new TestEnvDomain[1];
params[0] = qm;
mijdfb.setArguments(params);
mijdfb.afterPropertiesSet;
org.quartz.JobDetail jd=new JobDetailImpl;
jd=mijdfb.getObject;
scheduler.addJob(jd, true);/<code>

(2)實例化觸發器

首先實例化CronTriggerFactoryBean,然後添加對應job的時間表表達式等參數信息,然後調用afterPropertiesSet,這個方法和MethodInvokingJobDetailFactoryBean 中的afterPropertiesSet類似,最終實例化一個CronTriggerImpl

<code>String triggerName=qm.getEnvId +"Trigger";
CronTriggerFactoryBean ctb=new CronTriggerFactoryBean;

ctb.setName(triggerName);
ctb.setCronExpression(qm.getCronExpression);
ctb.setJobDetail(jd);
ctb.afterPropertiesSet;
CronTrigger cronTrigger= ctb.getObject;
scheduler.scheduleJob(cronTrigger);
scheduler.rescheduleJob(cronTrigger.getKey, cronTrigger);/<code>

以上對Scheduled註解方式、配置文件方式,CronTriggerFactoryBean,SimpleTriggerFactoryBean配置文件方式,CronTriggerFactoryBean通過java任務管理器動態創建等不同定時任務配置方法進行了較詳細的說明。

通過以上各種配置方式的對比,可以看出,各種配置方式操作都不是特別複雜,相對來說Scheduled配置方式更加的輕量級一些,在一些相對不是很複雜、不涉及線程特別多的場景下可以使用。

Quartz配置方式是一種更加重量級、多線程、分佈式等場景下的定時任務配置方式。希望對遇到定時任務配置問題的朋友,可以做一些比較,選擇合適的定時任務配置方式。


分享到:


相關文章: