上節(jié)講了Bean實例化的內(nèi)部機制,這里再復(fù)述一遍:
從實例化的過程中可以看出,BeanDefinition起到中流砥柱的作用。因為BeanDefinition是配置文件<bean>元素標簽在容器中的內(nèi)部表示。比如,<bean>標簽在XML中有class,scope,lazy-init等屬性,那么在BeanDefinition中則有相應(yīng)的beanClass,scope,lazyInit屬性等。 BeanDefinition接口的繼承結(jié)構(gòu)如圖: 頂級的BeanDefinition其實是個接口,下面的AbstractBeanDefinition實現(xiàn)了這個接口,而最下面的ChildBeanDefinition和RootBeanDefinition分別繼承了AbstractBeanDefinition。來看一個XML配置: 1 <!-- 父子<bean> --> 2 <bean id="car0" class="com.baobaotao.tagdepend.Car" 3 p:brand="紅旗CA72" p:price="2000.00" p:color="黑色" 4 abstract="true"/> 5 6 <bean id="car3" parent="abstractCar"> 7 <property name="color" value="紅色"/> 8 </bean> car3繼承了car0,對應(yīng)繼承結(jié)構(gòu)圖,car3使用的是ChildBeanDefinition,car0使用的是RootBeanDefinition,也就是說,car3的屬性多于car0,而不管是car3還是car0,它們都有共性(即使配置文件中沒寫,也是隱形存在的,比如上面講的scope,lazyInit等),這些共性將提取在AbstractBeanDefinition中。如果<bean>標簽沒有繼承關(guān)系,那么它將使用默認的RootBeanDefinition,在2.5版本之后加了一個GenericBeanDefinition,因為自身優(yōu)勢而成為默認的使用類。
下面是BeanDefinition的API:(在線文檔:http://tool.oschina.net/apidocs/apidoc?api=Spring-3.1.1)
在方法概述中,我們可以看到這個接口中定義了所有<bean>屬性的方法接口,比如singleton、prototype,lazyInit等。
由于API里的方法很多,我截取幾個例子: 這些get方法是獲取共性類的屬性值,實際上,共性屬性的默認值在定義成員變量時就已經(jīng)默認給定了,請看代碼: 1 private volatile Object beanClass; 2 3 private String scope = SCOPE_DEFAULT; 4 5 private boolean singleton = true; 6 7 private boolean prototype = false; 8 9 private boolean abstractFlag = false; 10 11 private boolean lazyInit = false; 12 13 private int autowireMode = AUTOWIRE_NO; 14 15 private int dependencyCheck = DEPENDENCY_CHECK_NONE; 16 17 private String[] dependsOn; 18 19 private boolean autowireCandidate = true; 20 21 private boolean primary = false; 上面代碼截取的是AbstractBeanDefinition的源碼,可以看到許多<bean>標簽的屬性默認值。
一開始創(chuàng)建的BeanDefinition由于占位符的原因是個半成品,需要用Bean工廠后處理器對Bean進行處理,處理完之后由InstantiationStrategy對BeanDefinition進行實例化。后面我們會詳細介紹InstantiationStrategy。 BeanDefinition是如何創(chuàng)建的,XML又是如何被解析的?這些問題需要深入到源碼中去尋求答案,在講完IoC部分之后,我將對源碼進行剖析,深入探究其奧妙,希望大家繼續(xù)支持并關(guān)注我的博客。 |
|
來自: 昵稱10504424 > 《工作》