1. 程式人生 > >Spring對註解(Annotation)處理原始碼分析2——解析和注入註解配置的資源

Spring對註解(Annotation)處理原始碼分析2——解析和注入註解配置的資源

1.類內部的註解,如:@Autowire@Value@Required@Resource以及EJBWebSerivce相關的註解,是容器對Bean物件例項化和依賴注入時,通過容器中註冊的Bean後置處理器處理這些註解的。

2.Spring中處理註解的Bean後置處理器:

當使用Spring的註解功能時,在Spring配置檔案中新增如下配置開啟Spring的註解處理器:

 

上面的配置將隱式地向Spring容器註冊CommonAnnotationBeanPostProcessor

PersistenceAnnotationBeanPostProcessor以及4個專門用於處理註解的Bean後置處理器。

下面將具體介紹這4個註解後置處理器。

:

Spring容器專門處理配置了自動依賴注入裝配相關注解(@Autowire@Value以及其他JSR-330註解)Bean後置處理器,其主要功能原始碼如下:

(1).的構造方法:

AutowiredAnnotationBeanPostProcessor只有一個的構造方法,其原始碼如下:

 

(2).為指定類選擇其合適的構造方法:

容器對指定類進行自動依賴注入裝配(autowiring)時,容器需要對Bean呼叫合適的構造方法建立例項物件,AutowiredAnnotationBeanPostProcessor為指定類選擇相應的構造方法,原始碼如下:

 

(3).AutowiredAnnotationBeanPostProcessor對方法和屬性的依賴注入:

Spring容器對配置了autowire相關注解的Bean進行依賴注入時,後置處理器對屬性和物件進行自動注入處理,原始碼如下:

 

(4).AutowiredAnnotationBeanPostProcessor對欄位和方法的注入:

a.AutowiredAnnotationBeanPostProcessor對欄位的注入是通過AutowiredFieldElement類的inject方法實現的,原始碼如下:

 

b.AutowiredAnnotationBeanPostProcessor對欄位的注入是通過AutowiredMethodElement類的inject方法實現的,原始碼如下:

 

beanFactory.resolveDependencyregisterDependentBeans方法我們在Spring容器依賴注入原始碼分析中已經分析過,這裡就不再具體分析。

後置處理器主要解析autowire相關的註解,即@Autowire@Value等。

4.

CommonAnnotationBeanPostProcessorSpring中用於處理JavaEE5中常用註解(主要是EJB相關的註解)Java6中關於JAX-WS相關的註解,可以處理PostConstruct@PreDestroyBean生命週期相關事件的註解,該後置處理最核心的是處理@Resource註解,同時還可以處理JAX-WS相關的註解,按照其主要功能分析其主要實現原始碼:

(1).靜態初始化塊和建構函式:

 

CommonAnnotationBeanPostProcessor的靜態初始化塊和構造方法可以看出該後置處理器主要處理EJBWebService相關的註解,以及Bean生命週期事件的相關注解。

(2).CommonAnnotationBeanPostProcessor對屬性值的查詢:

CommonAnnotationBeanPostProcessor對普通屬性的處理與AutowiredAnnotationBeanPostProcessor的處理基本相同,不同在於查詢屬性值的方法不同,通過autowire相關注解的required配置獲取依賴的屬性值,則通過對@Resource註解的解析獲取屬性的值,CommonAnnotationBeanPostProcessor獲取屬性值的主要原始碼:

 

從上面的原始碼中,我們可以看到,對於方法上面的註解,EJBWebService相關注解以及@Resource只能在單個引數的方法上配置,否則會有異常丟擲。

(3).根據給定名稱或者型別獲取資源物件:

WebServiceEJB相關注解以及@Resource主要是為所新增的欄位或者方法注入所需要的資源,CommonAnnotationBeanPostProcessor類中獲取資源的原始碼如下:

 

(4)[email protected]WebServiceEJB相關注解的解析和屬性注入:

Spring中,@Resource註解是由類解析的,WebService相關注解是由類解析的,EJB相關注解是由EjbRefElement類解析的,下面就具體分析其解析的實現

a.ResourceElement解析@Resource註解和屬性注入:

ResourceElementSpring中用於解析@Resource註解和屬性注入的類,原始碼如下:

 

解析WebService相關的註解和屬性注入:

WebServiceRefElementSpring中用於解析WebService相關注解和屬性注入的類,原始碼如下:

 

通過上面的原始碼分析,我們知道Spring容器在對WebSerice進行注入時,首先通過JNDI查詢容器中的例項物件,如果沒有找到,則根據wsdl檔案例項化WebService物件,如果沒有指定wsdl檔案的路徑,則根據型別利用JDK的反射機制生成WebService例項物件,完成注入。

c.EjbRefElement解析EJB相關的註解和屬性注入:

EjbRefElementSpring中用於解析EJB相關注解和屬性注入的類,原始碼如下:

 

從上面對@ResourceWebServiceEJB相關注解解析原始碼的分析中,我們可以看出,Spring主要使用JDNI查詢方式獲取這三類註解資源,另外,由原始碼的“if (this.memberinstanceof Method&& resourceName.startsWith("set") && resourceName.length() > 3)”判斷條件,我們可以看出這三類註解只能新增在欄位上,或者set屬性方法上,在get屬性方法上新增這三類註解將是無法被解析的。

5.RequiredAnnotationBeanPostProcessor

Spring中用於處理@Required註解的,@Required註解強制要求Bean屬性必須被配置,當Spring容器對Bean的屬性進行依賴注入時,配置了@Required註解的屬性,Spring容器會檢查依賴關係是否設定,按照其主要功能分析其主要實現原始碼:

 

6.

PersistenceAnnotationBeanPostProcessorSpring中用於處理JPA相關注解的Bean後置處理器,主要解析和處理@PersistenceUnit@PersistenceContext註解,其主要作用是為JPA的實體管理器工廠(EntityManagerFactory)和實體管理器(EntityManager)注入相應的持久化單元(PersistenceUnit)或持久化上下文(PersistenceContext)。按照其主要功能分析其主要實現原始碼:

(1).處理和查詢持久化元資訊:

 

(2).根據持久化單元名稱獲取持久化上下文、持久化單元和實體管理器工廠:

PersistenceAnnotationBeanPostProcessor最重要的核心功能就是根據持久化單元名稱獲取相應的持久化上下文,持久化單元或者實體管理器工廠,原始碼如下: