Timer定时器在项目初始化的时候注入service为null
问题
在自定义的timer中需要注入业务类接口(service)完成相应的操作,但是在通过@Autowired注入后为null,导致在执行业务操作的时候报空指针错误。
源代码
需要做一个定时更新数据库的程序,因为比较简单,所以选择了Timer。
定义更新数据定时器UpdateDbTimerWorker
public class UpdateDbTimerWorker extends TimerTask {
@Autowired
private UpdateDbService updateDbService;
@Override
public void run() {
if (TaskQueue.isBlock()) {
UpdateDbTask task = null;
try {
task = TaskQueue.take();
if (task != null) {
String type = task.getType();
if ("insert".equals(type)) {
updateDbService.insert(task);
} else {
updateDbService.update(task);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
}
}
UpdateDbService
public interface UpdateDbService {
/**
* 插入
* @param task
*/
void insert(UpdateDbTask task) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException;
/**
* 更新
* @param task
*/
void update(UpdateDbTask task) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException;
}
为了获取到这个注入对象,只能我们手动注入了,就是通过获取上下文对象,然后再对这个对象进行解析,然后取出自己所要的那个对像。
SpringContextUtil工具类
@Component
public class SpringContextUtil implements ApplicationContextAware {
/**
* Spring应用上下文环境
*/
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取对象
*
* @param beanName
* @return Object 一个以所给名字注册的bean的实例
*/
public static Object getBean(String beanName){
return applicationContext.getBean(beanName);
}
/**
* 获取类型为requiredType的对象
*
* @param clz
* @return
* @throws BeansException
*/
public static <T> T getBean(Class<T> clz) throws BeansException {
@SuppressWarnings("unchecked")
T result = (T) applicationContext.getBean(clz);
return result;
}
/**
* @param name
* @return Class 注册对象的类型
* @throws NoSuchBeanDefinitionException
*/
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
return applicationContext.getType(name);
}
/**
* 如果给定的bean名字在bean定义中有别名,则返回这些别名
*
* @param name
* @return
* @throws NoSuchBeanDefinitionException
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return applicationContext.getAliases(name);
}
}
解决
在定时器中通过SpringContextUtil获取bean
public class UpdateDbTimerWorker extends TimerTask {
private UpdateDbService updateDbService = SpringContextUtil.getBean(UpdateDbServiceImpl.class);
后略...
}