1. 程式人生 > >Spring源碼分析之IOC容器(一)

Spring源碼分析之IOC容器(一)

util 感覺 不能 end bsp initial 博文 要掌握 sof

  Spring作為當今風靡世界的Web領域的第一框架,作為一名Java開發程序員是一定要掌握的,除了需要掌握基本的使用之外,更需要掌握其實現原理,因為我們往往在開發的過程中,會出現各種各樣的異常問題。而且這樣的問題去百度有時候往往也找不到特別有效的解決方法,因為問題的原因非常多而百度的又不準確,這個時候怎麽辦呢?在熟練掌握Spring代碼的情況下,我們可以根據提示的異常信息,去跟到源代碼的地方,可以準確的定位到異常的所在,這就猶如debug調試自己的業務邏輯一樣輕松了,所以Spring的源代碼非常值得一讀。還有另外一個好處就是,Spring的構建非常的復雜,但同時它的設計也是非常的靈性的,不僅對我們自身的軟件設計能力會有很大的提高,感受到軟件設計的魅力所在。其實我本來是想等我把Spring的代碼完全讀透之後再寫下這些博文,但是感覺寫博客就相當於對自己的一個總結,可能邊分析邊學下來比較好,下面,就讓我來一點一點分析Spring的源碼。

  Spring家族的構成非常的龐大,網上有很多圖,我也隨手拎了一張過來,如下圖所示:

技術分享

  通過這張圖,我們可以看到處於最下面的是Beans、Core、Context和SpEl四個模塊,SpEl是Spring的一個表達式,並沒有那麽重要,所以我們暫時就不去分析這個了。重點講一講其他的三個模塊。我借用淘寶大神許令波在《深入分析Web技術內幕》一書中的比喻,Beans相當於Java的對象,而Java對象封裝了數據,一個IOC容器中往往會有很多的Bean,我們在這裏可以將Bean比喻成演員。Context就相當於容器,給演員,也就是Bean提供了一個舞臺,那麽最後演員有了,舞臺也有了,每個演員不可能只會自己演自己的,也不可能沒有道具和服裝,所以這個時候Core組件排上用場了,按照這麽說的話,Core組件可以維護每個Bean之間的關系,也就相當於這些演員在舞臺上要演出的“道具”和“服裝”等等。如果這個比喻你還不能理解的話,可以再打一個比喻。三國演義中,每個主公都有自己的武將,可以把武將就看作一個Bean,主公作為一城之主,當敵人來犯的時候必須調配武將,給他們分配兵馬,而且打仗的時候需要各個武將之間的配合方能取勝,這個時候我們就可以把主公當作一個容器,主公分發的兵馬,糧草器械等等是Core組件,這個用來維持每個武將之間的關系。這三者之間的關系大概就是這樣了,只要理解了其實很多情景都可以用IOC來解釋了。今天我們就主要說說IIOC三大組件之一的Bean組件。

  首先我們要知道Bean組件是怎麽設計的,有哪些類和接口定義了這些功能,畫出UML圖來表示這些結構和組成。Bean組件位於Spring的org.springframework.beans包下面,如圖所示:

技術分享

這個包其實解決了三件事情:Bean的定義、Bean的創建和Bean的解析。而我們在使用Spring框架的時候要做的就是完成Bean的創建,也就是編寫配置文件。Spring的Bean組件的實現完全上是一個工廠模式,位於最頂層的是一個名叫BeanFactory的接口,IOC功能的Bean組件的類結構如下圖所示:

技術分享

最終的實現類是DefaultListableBeanFactory,它實現了所有的接口和類。最頂層的類是BeanFactory,從字面的意思可以理解為bean工廠,是bean組成的最基本的類。它有三個子接口:ListableBeanFactory、HierarchicalBeanFactory和AutowireCapableBeanFactory三個接口。這三個接口的功能肯定是不一樣的,分別將代碼貼出來。

ListableBeanFactory:這個接口的Bean工廠表示裏面的bean元素是可列表的

 1 package org.springframework.beans.factory;
 2 
 3 import java.lang.annotation.Annotation;
 4 import java.util.Map;
 5 
 6 import org.springframework.beans.BeansException;
 7 
 8 public interface ListableBeanFactory extends BeanFactory {
 9       
10       boolean containsBeanDefinition(String beanName);
11     
12       int getBeanDefinitionCount();
13       
14       String[] getBeanDefinitionNames();
15      
16       String[] getBeanNamesForType(Class<?> type);
17     
18       String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
19 
20       <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
21 
22       <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
23             throws BeansException;
24 
25       Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
26             throws BeansException;
27 
28       <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);
29 }   

HierarchicalBeanFactory:這個接口的Bean表示這些Bean是有繼承關系的。

 1 package org.springframework.beans.factory;
 2 
 3 
 4 public interface HierarchicalBeanFactory extends BeanFactory {
 5     
 6     
 7     BeanFactory getParentBeanFactory();
 8 
 9     boolean containsLocalBean(String name);
10 
11 }

AutowireCapableBeanFactory:表示Bean是可以自動裝配的。

 1 package org.springframework.beans.factory.config;
 2 
 3 import java.util.Set;
 4 
 5 import org.springframework.beans.BeansException;
 6 import org.springframework.beans.TypeConverter;
 7 import org.springframework.beans.factory.BeanFactory;
 8 
 9 public interface AutowireCapableBeanFactory extends BeanFactory {
10 
11     int AUTOWIRE_NO = 0;
12 
13     int AUTOWIRE_BY_NAME = 1;
14 
15     int AUTOWIRE_BY_TYPE = 2;
16 
17     int AUTOWIRE_CONSTRUCTOR = 3;
18 
19     @Deprecated
20     int AUTOWIRE_AUTODETECT = 4;
21 
22 
23     //-------------------------------------------------------------------------
24     // Typical methods for creating and populating external bean instances
25     //-------------------------------------------------------------------------
26 
27     <T> T createBean(Class<T> beanClass) throws BeansException;
28 
29     void autowireBean(Object existingBean) throws BeansException;
30 
31     Object configureBean(Object existingBean, String beanName) throws BeansException;
32 
33     Object resolveDependency(DependencyDescriptor descriptor, String beanName) throws BeansException;
34 
35 
36     //-------------------------------------------------------------------------
37     // Specialized methods for fine-grained control over the bean lifecycle
38     //-------------------------------------------------------------------------
39 
40     Object createBean(Class beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
41 
42     Object autowire(Class beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
43 
44     void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
45             throws BeansException;
46 
47     void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
48 
49     Object initializeBean(Object existingBean, String beanName) throws BeansException;
50 
51     Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
52             throws BeansException;
53 
54     Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
55             throws BeansException;
56 
57     Object resolveDependency(DependencyDescriptor descriptor, String beanName,
58             Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;
59 
60 }

這四個接口共同定義了Bena的集合,Bean之間的關系和Bean的行為。

Bean的定義

Bean的定義主要由BeanDefinition描述,類的結構圖如下:

技術分享

Bean的解析

Bean解析的過程非常的復雜,功能被分得很細,因為這裏需要被擴展的地方很多,必須保證有足夠的靈活性,以應對可能的變化。Bean的解析主要就是對Spring配置文件的解析,這個解析過程如圖所示:

技術分享

以上就包括了Spring IOC中的Bean組件的一些基本的定義和類的結構,請大家參考。

Spring源碼分析之IOC容器(一)