Spring與Quartz實現動態更新定時任務
阿新 • • 發佈:2019-01-22
applicationContext-quartz.xml配置:
我們只需要專注於QuartzJobBean子類中的executeInternal方法的實現,該方法裡只需要放置我們需要定期執行的任務程式碼即可<!-- 任務排程測試實現一 : 自定義的任務物件com.bocloud.equipment.test.ExampleJob 必須繼承QuartzJobBean類,實現抽象方法executeInternal 每次執行任務時,都會新建立一個任務物件. --> <bean id="myJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"> <!-- 屬性jobClass不能通過ref來指定為exampleJob物件,該屬性接收的是Class型別的引數 進行任務排程時,每次都是一個新的jobClass物件去執行executeInternal方法 --> <property name="jobClass" value="com.bocloud.equipment.test.ComputerInfoGatherJob" /> </bean> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="myJobDetail" /> <property name="cronExpression" value="0/10 * * * * ?" /> </bean> <bean id="computerInfoGatherScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigger" /> </list> </property> </bean>
<!-- 任務除錯實現測試二 : 屬性targetObject:指定執行任務的物件 屬性targetMethod:指定執行任務的方法,該方法必須是無參方法 --> <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="computerService" /> <property name="targetMethod" value="list" /> </bean> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="jobDetail" /> <property name="cronExpression" value="0/10 * * * * ?" /> </bean> <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigger" /> </list> </property> </bean>
targetObject引用參考的物件,就是Spring框架幫我們生成好的自定義的任務bean物件,不過要注意的是,targetMehthod指定的方法必須是無參的(Spring也支援可以帶有引數的任務方法,具體的沒注意,以後搞明白了再更新上來,不過一般我們執行定期任務時都不需要動態引數)
package com.bocloud.equipment.test; import java.text.ParseException; import java.util.Date; import org.quartz.CronTrigger; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.impl.StdScheduler; import org.springframework.scheduling.quartz.QuartzJobBean; import org.springframework.web.context.ContextLoaderListener; import org.springframework.web.context.WebApplicationContext; import com.bocloud.equipment.service.ComputerServiceImpl; public class ComputerInfoGatherJob extends QuartzJobBean { private static long count = 0L; @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { System.out.println("*******************************"); count++; System.out.println(new Date() + "\t:任務排程開始第" + count + "次"); WebApplicationContext webContext = ContextLoaderListener.getCurrentWebApplicationContext(); ComputerServiceImpl csi = webContext.getBean(ComputerServiceImpl.class); /* * 更改任務排程的週期時間: * 1,不要呼叫StdScheduler的shutdown()方法,shutdown()以後無法再start() * 2,可使用standby()暫停排程任務,再start() * 3,設定cron後,要呼叫rescheduleJob(TriggerKey triggerKey, Trigger newTrigger) */ /* * 這裡獲取SchedulerFactoryBean時,不要通過getBean(Class<T> requiredType) * 或getBean(String name, Class<T> requiredType) * 否則會提示轉型錯誤: * org.quartz.impl.StdScheduler無法轉型為指定的需要型別: * org.springframework.scheduling.quartz.SchedulerFactoryBean * 直接使用getBean(String name)再強轉為org.quartz.impl.StdScheduler即可 */ StdScheduler scheduler = (StdScheduler)webContext.getBean("computerInfoGatherScheduler"); if (count == 2) { System.out.println("Computer資訊採集任務暫停!"); try { //獲取此排程器中名稱為cronTrigger(配置檔案中CronTriggerFactoryBean的名稱)的Trigger物件 CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger("cronTrigger", Scheduler.DEFAULT_GROUP); System.out.println("設定Computer資訊採集任務週期為:5秒"); cronTrigger.setCronExpression("0/5 * * * * ?"); /* * public Date rescheduleJob(String triggerName, String groupName, Trigger newTrigger) throws SchedulerException * triggerName:要被替換的Trigger的名稱 * groupName:要被替換的Trigger的組名 * newTrigger:要新儲存的Trigger物件 * 返回:如果沒找到triggerName則返回空,否則返回第一次觸發任務的時間 */ Date date = scheduler.rescheduleJob("cronTrigger", Scheduler.DEFAULT_GROUP, cronTrigger); System.out.println("=========Computer資訊採集任務重新開始========="); if (date == null) { throw new RuntimeException("更改任務週期後,重新排程任務失敗!!!"); } } catch (SchedulerException e) { System.out.println("獲取CronTrigger物件時出現異常"); e.printStackTrace(); } catch (ParseException e) { System.out.println("解析cron表示式時出現異常"); e.printStackTrace(); } } if (count == 4) { System.out.println("暫停任務排程!!10秒後重新開始"); //暫停排程任務:排程器中的所有Trigger對應的任務都會暫停,要暫停指定Trigger的話,呼叫pauseTrigger() scheduler.standby(); try { Thread.sleep(10000); //判斷排程器當前是否在暫停狀態 if (scheduler.isInStandbyMode()) { scheduler.start(); } System.out.println("任務排程又重新開始"); } catch (InterruptedException e) { e.printStackTrace(); } catch (SchedulerException e) { e.printStackTrace(); } } csi.list(0, null, null); } }
參考: