作項目過程當中,常常碰到有定時任務中須要調用spring中自動注入的bean,若是直接在定時任務類中自動注入Service 、Dao的bean,都是不能實現的,由於任務每次都啓用一個新的線程。spring
能夠採用實現ApplicationContextAware接口,每次啓動新的線程,都從spring初始化的bean對象中得到bean。apache
注:spring 2.5+QuartZ 1.6.1app
【實現類】:ide
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;函數
public class SpringContextHolder implements ApplicationContextAware {this
private static ApplicationContext applicationContext;線程
/**
* 實現ApplicationContextAware接口的context注入函數, 將其存入靜態變量.
*/
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextHolder.applicationContext =applicationContext;
}
xml
/**
* 取得存儲在靜態變量中的ApplicationContext.
*/
public static ApplicationContext getApplicationContext() {
checkApplicationContext();
return applicationContext;
}
/**
* 從靜態變量ApplicationContext中取得Bean, 自動轉型爲所賦值對象的類型.
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
checkApplicationContext();
return (T) applicationContext.getBean(name);
}對象
/**
* 從靜態變量ApplicationContext中取得Bean, 自動轉型爲所賦值對象的類型.
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(Class<T> clazz) {
checkApplicationContext();
return (T) applicationContext.getBeansOfType(clazz);
}接口
private static void checkApplicationContext() {
if (applicationContext == null)
throw new IllegalStateException("applicaitonContext未注入,請在applicationContext.xml中定義SpringContextUtil");
}
}
【定時任務類】
import org.apache.log4j.Logger;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class QuartzJob extends QuartzJobBean{
private SpringContextHolder springContextHolder;
Logger logger = Logger.getLogger(this.getClass());
@Override
protected void executeInternal(JobExecutionContext arg0)
throws JobExecutionException {
IUserService s=springContextHolder.getBean("userService");
//...
}
}
【spring配置文件】
<bean name="springContextHolder" class="....SpringContextHolder" lazy-init="false" /><!-- 定義調用對象和調用對象的方法 --><bean name="quartzJob" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass" value="....QuartzJob" /> <property name="jobDataAsMap"> <map> <entry key="springContextHolder" value-ref="springContextHolder" /> </map> </property> </bean> <!-- 定義觸發時間 --><bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="quartzJob"/> <!-- cron表達式:秒 分 時 星期 月 年 --> <property name="cronExpression" value="5,25,45 * * * * ?" /></bean><!-- 總管理類 若是將lazy-init='false'那麼容器啓動就會執行調度程序 --><bean id="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigger"/> </list> </property></bean>