springboot中 有時會遇到一些依賴注入爲null的情況,
當我們在異步類或者有異步方法的類中 用@Autowired 或者用@Resource 無法注入
此時我的解決辦法就是從ApplicationContext中獲取Bean的方式進行注入
上代碼:
@Slf4j
@Lazy(false)
@Component
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
private static ApplicationContext applicationContext = null;
/**
* 取得存儲在靜態變量中的ApplicationContext.
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 實現ApplicationContextAware接口, 注入Context到靜態變量中.
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextHolder.applicationContext = applicationContext;
if (applicationContext != null) {
log.info(">>>>>>>>>>>>>>成功初始化 applicationContext ");
} else {
log.info(">>>>>>>>>>>>>>applicationContext 沒有被初始化");
}
}
/**
* 從靜態變量applicationContext中取得Bean, 自動轉型爲所賦值對象的類型.
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
return (T) applicationContext.getBean(name);
}
/**
* 從靜態變量applicationContext中取得Bean, 自動轉型爲所賦值對象的類型.
*/
public static <T> T getBean(Class<T> requiredType) {
return applicationContext.getBean(requiredType);
}
/**
* 清除SpringContextHolder中的ApplicationContext爲Null.
*/
public static void clearHolder() {
if (log.isDebugEnabled()) {
log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
}
applicationContext = null;
}
/**
* 通過name 及class獲取bean,相對更精確
* @param name
* @param clazz
* @param <T>
* @return
*/
public static<T> T getBean(String name,Class<T> clazz){
return applicationContext.getBean(name,clazz);
}
/**
* 發佈事件
*
* @param event
*/
public static void publishEvent(ApplicationEvent event) {
if (applicationContext == null) {
return;
}
applicationContext.publishEvent(event);
}
/**
* 實現DisposableBean接口, 在Context關閉時清理靜態變量.
*/
@Override
@SneakyThrows
public void destroy() {
SpringContextHolder.clearHolder();
}
}
其中@Lazy(false) 這個註解的作用是爲了讓該類在啓動時加載, 因爲默認是 懶加載, 有可能會出現 ApplicationContext爲空的現象,
特別是在啓動的時候有些類需要通過這個類獲取對應的bean的時候
怎麼通過這個類進行注入呢 ?
只需要 調用 SpringContextHolder.getBean() 方法,傳入要注入的類或者Bean的名稱即可!!
當我們因爲依賴注入出現循環引用的時候也可以通過它進行解決,
抽象類無法注入也可以