問題描述
在開發中,因某些業務邏輯執行時間太長,我們常使用線程來實現。常規服務實現類中,使用 @Autowired 來注入Bean,來調用其中的方法。但如果在線程類中使用@Autowired注入的Bean,調用方法會拋出ava.lang.NullPointerException異常。過程如下:
注入
@Autowired
TtaskSubitemDao taskSubitemDao;
使用
List<TtaskSubitem> taskSubitemList = taskSubitemDao.queryTaskSubitemByTypeId(taskBase.getTypeId());
異常
解決方法
ApplicationContextAware的作用是可以方便獲取Spring容器ApplicationContext,從而可以獲取容器內的Bean。ApplicationContextAware接口只有一個方法setApplicationContext,如果實現了這個方法,那么Spring創建這個實現類的時候就會自動執行這個方法,把ApplicationContext注入到這個類中,也就是說,spring 在啟動的時候就需要實例化這個 class(如果是懶加載就是你需要用到的時候實例化),在實例化這個 class 的時候,發現它包含這個 ApplicationContextAware 接口的話,sping 就會調用這個對象的 setApplicationContext 方法,把 applicationContext Set 進去了。
實現ApplicationContextAware

import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; @Component public class ApplicationContextProvider implements ApplicationContextAware { /** * 上下文對象實例 */ private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } /** * 獲取applicationContext * * @return */ public static ApplicationContext getApplicationContext() { return applicationContext; } /** * 通過name獲取 Bean. * * @param name * @return */ public static Object getBean(String name) { return getApplicationContext().getBean(name); } /** * 通過class獲取Bean. * * @param clazz * @param <T> * @return */ public static <T> T getBean(Class<T> clazz) { return getApplicationContext().getBean(clazz); } /** * 通過name,以及Clazz返回指定的Bean * * @param name * @param clazz * @param <T> * @return */ public static <T> T getBean(String name, Class<T> clazz) { return getApplicationContext().getBean(name, clazz); } }
線程實現類中使用
TtaskSubitemDao taskSubitemDao = ApplicationContextProvider.getBean(TtaskSubitemDao.class); List<TtaskSubitem> taskSubitemList = taskSubitemDao.queryTaskSubitemByTypeId(taskBase.getTypeId());
這樣就獲取到Bean,繼而查詢數據,不會報出異常。