作项目过程当中,常常碰到有定时任务中须要调用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>