以代碼的方式管理quartz定時任務的暫停、重啟、刪除、添加等
【前言】在項目的管理功能中,對定時任務的管理有時會很常見。因為我們不能指望只在配置文件中配置好定時任務就行了,因為如果要控制定時任務的 “暫停” 呢?暫停之後又要在某個時間點 “重啟” 該定時任務呢?或者說直接 “刪除” 該定時任務呢?要改變某定時任務的觸發時間呢? “添加” 一個定時任務對於系統的使用者而言,是不太現實的,因為一個定時任務的處理邏輯他是不可能完成的,還是必須得由開發人員去添加。一般來說,是針對 “已有” 定時任務進行的一些操作,這時候就必須要用到代碼來操作了,因為此時通過配置來管控是不太現實的。
版本:Spring4.x + quartz2.x
首先,開發人員會在配置文件中配置一個定時任務(定時任務的實現略……)
Java代碼
- <bean id="job1" class="org.test.job.TestJob2" />
- <!-- 定義觸發器來管理任務bean -->
- <bean id="cronTriggerJob1"
- class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"
- p:cronExpression="0 52 17 * * ? *" >
- <property name="jobDetail">
- <bean class="org.springframework.scheduling.quartz.JobDetailFactoryBean"
- p:durability="true"
- p:jobClass="org.test.job.TestJob1"
- />
- </property>
- </bean>
- </bean>
- <!-- 執行實際的調度 -->
- <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
- <property name="triggers">
- <list>
- <ref bean="cronTriggerJob1" />
- </list>
- </property>
- </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代碼
- //暫停
- //schduler.pauseTrigger(TriggerKey triggerKey)
- scheduler.pauseJob(JobKey.jobKey("job1"));//停止觸發器
- Thread.sleep(1000*60*2);
- //恢復
- //scheduler.resumeJob(JobKey jobKey)則可恢復一個具體的job,
- scheduler.resumeTrigger(TriggerKey.triggerKey("cronTriggerJob1"));
- Thread.sleep(1000*60*2);
- //刪除
- //沒有deleteTrigger的方法
- scheduler.deleteJob(JobKey.jobKey("job1"));
- Thread.sleep(1000*60*2);
- //刪除後再次嘗試重啟(會失效)
- 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定時任務的暫停、重啟、刪除、添加等