1. 程式人生 > >以代碼的方式管理quartz定時任務的暫停、重啟、刪除、添加等

以代碼的方式管理quartz定時任務的暫停、重啟、刪除、添加等

thread word p s setprop 相關 framework pri one org

【前言】在項目的管理功能中,對定時任務的管理有時會很常見。因為我們不能指望只在配置文件中配置好定時任務就行了,因為如果要控制定時任務的 “暫停” 呢?暫停之後又要在某個時間點 “重啟” 該定時任務呢?或者說直接 “刪除” 該定時任務呢?要改變某定時任務的觸發時間呢? “添加” 一個定時任務對於系統的使用者而言,是不太現實的,因為一個定時任務的處理邏輯他是不可能完成的,還是必須得由開發人員去添加。一般來說,是針對 “已有” 定時任務進行的一些操作,這時候就必須要用到代碼來操作了,因為此時通過配置來管控是不太現實的。

版本:Spring4.x + quartz2.x

首先,開發人員會在配置文件中配置一個定時任務(定時任務的實現略……)

Java代碼 技術分享圖片
  1. <bean id="job1" class="org.test.job.TestJob2" />
  2. <!-- 定義觸發器來管理任務bean -->
  3. <bean id="cronTriggerJob1"
  4. class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"
  5. p:cronExpression="0 52 17 * * ? *" >
  6. <property name="jobDetail">
  7. <bean class="org.springframework.scheduling.quartz.JobDetailFactoryBean"
  8. p:durability="true"
  9. p:jobClass="org.test.job.TestJob1"
  10. />
  11. </property>
  12. </bean>
  13. </bean>
  14. <!-- 執行實際的調度 -->
  15. <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  16. <property name="triggers">
  17. <list>
  18. <ref bean="cronTriggerJob1" />
  19. </list>
  20. </property>
  21. </bean>

我們怎麽根據配置的bean來操作該定時任務的管理呢?

需查閱spring4.x結合quartz2.x的底層API,並搞清楚以下概念:

1)Trigger trigger. trigger.getKey()會得到兩個東西——group:DEFAULT(默認的group name)、name(triggerName)。其中name對應的就是配置文件中配置的trigger的bean的id(或name)

2)trigger.getJobKey()一樣會得到兩個東西——group:DEFAULT(默認的group name)、name(jobName)。其中jobName對應的就是配置文件中job的bean的id或name(本例為job1)

註:以上粗體字的部分即為代碼管理定時任務的關鍵之處!

3)如何根據jobName查找到他關聯到的trigger呢?

quartz1.x還有這種語法,不過quartz2.x已經廢除了:

quartz1.x Trigger trigger = sched.getTrigger(jobName,TRIGGER_GROUP_NAME);

quartz2.x的相關語法(Scheduler類的方法)更為豐富,如下:

public abstract List<? extends Trigger> getTriggersOfJob(JobKey paramJobKey)

throws SchedulerException;

public abstract List<String> getTriggerGroupNames()

throws SchedulerException;

public abstract Set<TriggerKey> getTriggerKeys(GroupMatcher<TriggerKey> paramGroupMatcher)

throws SchedulerException;

public abstract Trigger getTrigger(TriggerKey paramTriggerKey)

throws SchedulerException;

為了改變觸發時間,

Trigger trigger = TriggerBuilder.forJob(String jobName).newTrigger()..withSchedule(CronScheduleBuilder.cronSchedule(time))build();

然後再用Scheduler調度類去執行:

schedler.resumeTrigger(trigger.getKey());

根據trigger得到相應的JobDetail:

JobDetail jobDetail = (JobDetail) trigger.getJobDataMap().get("jobDetail");

下面是對定時任務的管理(暫停、重啟、刪除):

Java代碼 技術分享圖片
  1. //暫停
  2. //schduler.pauseTrigger(TriggerKey triggerKey)
  3. scheduler.pauseJob(JobKey.jobKey("job1"));//停止觸發器
  4. Thread.sleep(1000*60*2);
  5. //恢復
  6. //scheduler.resumeJob(JobKey jobKey)則可恢復一個具體的job,
  7. scheduler.resumeTrigger(TriggerKey.triggerKey("cronTriggerJob1"));
  8. Thread.sleep(1000*60*2);
  9. //刪除
  10. //沒有deleteTrigger的方法
  11. scheduler.deleteJob(JobKey.jobKey("job1"));
  12. Thread.sleep(1000*60*2);
  13. //刪除後再次嘗試重啟(會失效)
  14. scheduler.resumeTrigger(TriggerKey.triggerKey("cronTriggerJob1"));

代碼經測試,有效,並註意到:

當resume一個定時任務時,會立即執行該定時任務,執行完此次,然後再按原先設定的時間來定期執行

當刪除一個任務後,就算再次resume時,會失效,即並不會被恢復了。

=========================================

Spring bean必須註意的幾點:

1)bean的id和name是一回事兒;

2)當一個bean類繼承了InitializingBean接口後,必須實現其setBeanName(String name)抽象方法。name一般是bean的id或name屬性值,此時bean實例化時方法的順序為setProperties(String propName)->setBeanName()->afterPropertiesSet();

3)當為了獲得一個bean對外提供的接口方法時,必須先獲得這個bean的bean對象,通過Spring的SpringContextHolder.getBean(beanId) (其中beanId為bean的id或name屬性值)。而不能通過new或者getInstance(獲取單例)的方式,否則獲取不到該bean的其他屬性值!

以代碼的方式管理quartz定時任務的暫停、重啟、刪除、添加等