因為項目要求根據資料庫的配置資訊啟動Spring中的Quartz的任務,這樣就要求CronTriggerBean是動態多樣的。搜尋了很多文檔也沒有得其所以然,於是從Spring的配置資訊進行入手了。
網上介紹的各種例子中,預設都是以SchedulerFactoryBean進行開始的,也看到,裡面就一個參數就是triggers,那麼這樣就好說了,只要把trigger根據資料庫中的配置資訊進行產生就好了。
<bean id="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="doTime"/> </list> </property> </bean>
虛擬碼就是這樣的,寫個類繼承SchedulerFactoryBean
XXXvo = queryDB();CronTriggerBean bean = new CronTriggerBean();bean.setBeanName("beanNameFileSchedule"); bean.setCronExpression(xxxvo.getCronExpression()); jobDetailFactoryBean.setArguments(new Object[] { XXX}); bean.setJobDetail((JobDetail) jobDetailFactoryBean.getObject()); bean.afterPropertiesSet();this.setTriggers((CronTriggerBean[]) this.triggerBeanList .toArray(new CronTriggerBean[0])); this.afterPropertiesSet();
這樣基本上就大功告成了,但是調試過程中的小問題卻不少。
第一:CronTriggerBean和SchedulerFactoryBean都實現了InitializingBean介面,這樣的話,需要在兩個類的設定完屬性之後,需要手動的調用afterPropertiesSet的方法。
第二:CronTriggerBean需要設定BeanName,原因看一下CronTriggerBean方法的afterPropertiesSet就知道了,quartz的trigger如果沒有Name的話,就會報出來錯誤。
第三:Schedule的執行類配置到了Spring的XML中,但又因Schedule的執行類的執行方法有參數,這個參數又是動態傳入的。這樣的一個問題就是在SchedulerFactoryBean中調用下面的方法【jobDetailFactoryBean.setArguments(new Object[] { XXX});】設定參數的時候就已經晚了,因為Spring在執行個體化MethodInvokingJobDetailFactoryBean的時候就會報出來找不到方法的錯誤。現在的處理方式就是先在XML中為MethodInvokingJobDetailFactoryBean配置一個假的參數進去,只是為了佔據類型,然後在SchedulerFactoryBean中重新設定一遍,設定完成後,不能忘記調用afterPropertiesSet()方法,不然trigger不起作用。
寫的稍微亂了一些,就先記錄下來吧,後續再整理了。