問題:使用@Autowired無法注入Bean物件
阿新 • • 發佈:2019-02-03
問題
在公司的一個專案開發時,遇到了一個類的屬性無法注入的問題
public class DemoController extends BaseController implements BussinessProcessHandler {
@Autowired
DemoApi demoApi;
public void demo() {
demoApi.DemoService();
}
如上程式碼執行中報空指標異常,demoApi
的例項為null
,spring
容器沒有注入Bean
。
原因
起先認為是spring沒有掃描到元件。spring boot的註解@SpringBootApplication
@ComponentScan
,預設掃描是當前包及其子包下的所有目錄,檢視目錄結構是沒有問題的。所以不是掃描的問題。
後來發現這個類DemoController
的例項是反射生成的,並不由spring容器管理。
spring自動注入物件是通過建立一個BeanFactory
並傳入applicationContext
配置檔案物件,然後呼叫BeanFactory
的getBean
方法來實現相互依賴的物件獲取和裝配的。如果被注入的容器沒有在spring bean
中配置,而是通過反射途徑生成,不能獲取BeanFactory,就意味著不能進行自動注入。
解決辦法
自己建立一個SpringUtil
工具類元件,實現BeanFactoryAware
ApplicationContextAware
等spring
提供的介面,並通過例項手動獲取Spring
管理的bean
。
@Component
public class SpringUtil implements ApplicationContextAware {
//ApplicationContext物件是Spring開源框架的上下文物件例項,在專案執行時自動裝載Handler內的所有資訊到記憶體。
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
}
//獲取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
//通過name獲取 Bean.
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
//通過class獲取Bean.
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
//通過name,以及Clazz返回指定的Bean
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
手動獲取bean例項
public class DemoController extends BaseController implements BussinessProcessHandler {
//@Autowired
//DemoApi demoApi;
public void demo() {
//通過class獲取bean
DemoApi demoApi=SpringUtil.getBean(DemoApi.class);
demoApi.DemoService();
}
這樣再執行demoApi
就不為null
了。