1. 程式人生 > >問題:使用@Autowired無法注入Bean物件

問題:使用@Autowired無法注入Bean物件

問題

在公司的一個專案開發時,遇到了一個類的屬性無法注入的問題

public class DemoController extends BaseController implements BussinessProcessHandler {

    @Autowired
    DemoApi demoApi;
    
    public void demo() {
        demoApi.DemoService();
    }

如上程式碼執行中報空指標異常,demoApi的例項為nullspring容器沒有注入Bean

原因

起先認為是spring沒有掃描到元件。spring boot的註解@SpringBootApplication

繼承了掃描註解@ComponentScan,預設掃描是當前包及其子包下的所有目錄,檢視目錄結構是沒有問題的。所以不是掃描的問題。

後來發現這個類DemoController的例項是反射生成的,並不由spring容器管理。

spring自動注入物件是通過建立一個BeanFactory並傳入applicationContext配置檔案物件,然後呼叫BeanFactorygetBean方法來實現相互依賴的物件獲取和裝配的。如果被注入的容器沒有在spring bean中配置,而是通過反射途徑生成,不能獲取BeanFactory,就意味著不能進行自動注入。

解決辦法

自己建立一個SpringUtil工具類元件,實現BeanFactoryAware

或者ApplicationContextAwarespring提供的介面,並通過例項手動獲取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了。