解決Spring中Quart無法自動注入Bean問題
因專案需求,之前專案中已經有定時器的例子了,但是需求那邊過來的需求之前用的定時器並不能滿足,之前的定時器是用spring裡面的@Scheduled(cron = "0 0 0 * * ? ")這種方式,這是一種死的定時器,需求要的是動態定時器,使用者新增一個定時器,則系統就要自動新增一個定時器,等待執行。 才出現以下在執行的時候,出現物件空值的情況。
一般情況下,quartz的job中使用autowired註解注入的物件為空,這時候我們就要使用spring-quartz提供的AdaptableJobFactory類。
廢話不多說,直接上程式碼:
A.第一步:
這是一個(quartz的job中注入spring物件) 的類,查閱各種資料,這個類是必須的。
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
/**
*
* @author hhd
* quartz的job中注入spring物件
*
*/
public class SpringBeanJobFactory extends AdaptableJobFactory{
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
//呼叫父類的方法
Object jobInstance = super.createJobInstance(bundle);
//進行注入
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
這個類,說明一下。根據個人情況,網上查閱資料顯示:有人重新定義了一個Job的介面,然後定義一個AdaptableJobFactory類,讓這個類實現剛剛定義的Job介面,他這裡的意思就是說,定義一個新的介面,讓這個介面覆蓋原來的Job介面。接著就是quartz的job中注入spring物件 這個類,繼承 剛剛定義一個AdaptableJobFactory類。
這種情況,根據個人的需求試過了,根本不起作用,也是無法自動注入Bean。
B.第二步
配置spring.xml ,在spring.xml中新增以下bean 即可,注意:第一個bean裡面的bean為自己定義的類的路徑
<!-- 配置spring-quartz,解決quartz的job無法注入spring物件的問題 -->
<bean id="jobFactory" class="com.cmsz.monitor.schedule.SpringBeanJobFactory"/>
<!-- 排程器 -->
<bean name="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobFactory" ref="jobFactory"/>
</bean>
C.第三步:
定時器的執行器類。 這個類直接實現Job介面
import org.quartz.Job;
public class QuartzJobExample implements Job {
@Autowired
private RuleDao ruleDao;
/**
*執行方法
*/
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
//這裡可以嘗試列印注入的bean物件是否成功,如果不成功,會列印 出null 成功則列印一個物件出來。
System.out.println(ruleDao);
}
}
如果執行器類,列印的是一個物件,那麼你的問題也是解決了,但是對我的這個需求來說還是列印的null。
通過網上資料,看到一個,個人抱著並不成功的想法試著把程式碼寫上去,結果還真的打印出一個物件了。
程式碼如下:
//自動注入成員變數實現類
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
上面這行程式碼需要放在執行器類的執行方法裡面。
因為專案出現問題,查詢資料,並沒有一個完整的解決辦法,所以記錄這個人嘗試成功的過程。希望可以給大家帶來幫助。。。。