当调用一个定时器,但运行报错,空指针异常!也就是service、dao根本就没有注入成功、
原因是:继承TimerTask后,会直接运行run()方法,还没来得及执行标记进行注入。
这个时候引入SpringContextUtil的工具类
/**
* 项目名称:
* 类名: SpringContextUtil
* 描述: 获取bean的工具类,可用于在线程里面获取bean
* 创建人: -.-- .- -. --. --.. .. .- -.
* 修改备注:
* 版本:1.0
*/
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext context = null;
/* (non Javadoc)
* @Title: setApplicationContext
* @Description: spring获取bean工具类
* @param applicationContext
* @throws BeansException
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.context = applicationContext;
}
public static <T> T getBean(String beanName){
return (T) context.getBean(beanName);
}
public static String getMessage(String key){
return context.getMessage(key, null, Locale.getDefault());
}
}
<!-- 注册Spring工具类 -->
<bean id="springContextUtil" class="com.qinergy.util.SpringContextUtil"></bean>
所有关于定时任务有关的service、dao都需要
dao = SpringContexUtil.getBean("beanName");
比如 tourDao = SpringContextUtil.getBean("tourDao");
如果 我在controler中接受参数 放到map中 然后 调用任务 在任务中调用service的业务
那么久需要在任务中 写含参的构造方法 以及利用SpringContextUtil.getBean注入service
public class TourTask extends TimerTask {
private TourService tourService;//之前的写法是用@Autowired注入 但是spring无法注入子线程
private Map<String, Object> map;// controler接受的参数放在map中 调用定时任务的时候 参数需要传过来 所以 要有无参,含参构造
public TourTask(Map<String, Object> map) {
super();
tourService = SpringContextUtil.getBean("tourServiceImpl");//自己需要含参构造且注入service
this.map = map;
}
public TourTask() {
super();
}
@Override
public void run() {
try {
if (tourService == null) { //这个判断是用老方法@Autowired注入的时候 报空指针 测试的时候在这儿判断了一下 是因为service空 没有成功注入 所有service/dao注入需要SpringContextUtil.getBean才可以
System.out.println("---> null");
}
this.tourService.updOverhaulPlanRunFlat(this.map);//这里 调用service的业务逻辑
} catch (Exception e) {
e.printStackTrace();
}
}
}
没了 这就可以了