天天看點

Spring5源碼,@Autowired

一、@Autowired所具有的功能

二、在Spring中如何使用@Autowired

三、@Autowired注解背後的工作原理

@Autowired是一個用來執行依賴注入的注解。每當一個Spring管理的bean發現有這個注解時候,它會直接注入相應的另一個Spring管理的bean。

該注解可以在不同的層次上應用:

類字段:Spring将通過掃描自定義的packages(例如在我們所注解的controllers)或通過在配置檔案中直接查找bean。

方法:使用@Autowired注解的每個方法都要用到依賴注入。但要注意的是,方法簽名中呈現的所有對象都必須是Spring所管理的bean。如果你有一個方法,比如setTest(Article article, NoSpringArticle noSpringArt) ,其中隻有一個參數 (Article article)是由Spring管理的,那麼就将抛出一個org.springframework.beans.factory.BeanCreationException異常。這是由于Spring容器裡并沒有指定的一個或多個參數所指向的bean,是以也就無法解析它們。

構造函數:@Autowired的工作方式和方法相同。

對象注入需要遵循一些規則。一個bean可以按照下面的方式注入:

名稱:bean解析是通過bean名稱(看後面的例子)。

類型:解析過程基于bean的類型。

在某些情況下,@Autowired應該通過@Qualifier注解協作注入。例如下面幾個是相同類型的bean:

上面這種情況,假如隻是一個簡單的@Autowired,Spring根本不知道你要注入哪個bean。這就是為什麼我們要使用@Qualifier(value =“beanName”)這個注解。在我們的例子中,要從 com.migo.Comment這個類型的bean中區分comment1,comment2,我們可以寫下面的代碼:

在這一部分中,我們将使用XML配置的方式激活@Autowired注解來自動注入。然後,我們将編寫一個簡單的類并配置一些bean。最後,我們将分别在另外兩個類中使用它們:由@Controller注解的控件和不由Spring所管理的類。(為什麼用XML配置來做例子,我覺得這樣更直覺,其實XML和使用注解沒多少差別,都是往容器裡添加一些bean群組織下彼此之間的依賴而已)

我們從啟動注解的自動注入開始:

你必須将上面這個放在應用程式上下文配置中。它可以使在遇到@Autowired注解時啟用依賴注入。

現在,我們來編寫和配置我們的bean:

XML配置:

現在,我們打開http://localhost:8080/test來運作TestController。如預期的那樣,TestController的注解字段正确地自動注入,而TestNoSpring的注解字段并沒有注入進去:

TestNoSpring類不由Spring所管理。這就是為什麼Spring不能注入Comment執行個體的依賴。

Spring管理可用于整個應用程式的Java對象bean。他們所在的Spring容器,被稱為應用程式上下文。這意味着我們不需要處理他們的生命周期(初始化,銷毀)。該任務由此容器來完成。另外,該上下文具有入口點,在Web應用程式中,是dispatcher servlet。容器(也就是該上下文)會在它那裡被啟動并且所有的bean都會被注入。

<context:annotation-config />的定義:

可以看出 : 類内部的注解,如:@Autowired、@Value、@Required、@Resource以及EJB和WebSerivce相關的注解,是容器對Bean對象執行個體化和依賴注入時,通過容器中注冊的Bean後置處理器處理這些注解的。

是以配置了上面這個配置(<context:component-scan>假如有配置這個,那麼就可以省略<context:annotation-config />)後,将隐式地向Spring容器注冊AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor以及這4個專門用于處理注解的Bean後置處理器。

當 Spring 容器啟動時,AutowiredAnnotationBeanPostProcessor 将掃描 Spring 容器中所有 Bean,當發現 Bean 中擁有@Autowired 注解時就找到和其比對(預設按類型比對)的 Bean,并注入到對應的地方中去。 源碼分析如下:

通過org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor可以實作依賴自動注入。通過這個類來處理@Autowired和@Value這倆Spring注解。它也可以管理JSR-303的@Inject注解(如果可用的話)。在AutowiredAnnotationBeanPostProcessor構造函數中定義要處理的注解:

之後,有幾種方法來對@Autowired注解進行處理。

第一個,private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz)解析等待自動注入類的所有屬性。它通過分析所有字段和方法并初始化org.springframework.beans.factory.annotation.InjectionMetadata類的執行個體來實作。

InjectionMetadata類包含要注入的元素的清單。注入是通過Java的API Reflection (Field set(Object obj, Object value) 或Method invoke(Object obj,Object … args)方法完成的。此過程直接在AutowiredAnnotationBeanPostProcessor的方法中調用public void processInjection(Object bean) throws BeanCreationException。它将所有可注入的bean檢索為InjectionMetadata執行個體,并調用它們的inject()方法。

AutowiredAnnotationBeanPostProcessor類中的另一個重要方法是private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao)。它通過分析屬于一個字段或一個方法的所有注解來查找@Autowired注解。如果未找到@Autowired注解,則傳回null,字段或方法也就視為不可注入。

轉載:

芋道源碼