Bean的基本定义
<beans.../>元素是Spring配置文件的根元素,該元素可以指定如下屬性。
?? default-lazy-init:指定該<beans.../>元素下配置的所有Bean默認的延遲初始化行為。
?? default-merge:指定該<beans.../>元素下配置的所有Bean默認的merge行為。
?? default-autowire:指定該<beans.../>元素下配置的所有Bean默認的自動裝配行為。
?? default-autowire-candidates:指定該<beans.../>元素下配置的所有Bean默認是否作為自動裝配的候選Bean。
?? default-init-method:指定該<beans.../>元素下配置的所有Bean默認的初始化方法。
?? default-destroy-method:指定該<beans.../>元素下配置的所有Bean默認的回收方法。
?
提示:
<bean.../>元素是<beans.../>元素的子元素,<beans.../>元素可以包含多個<bean.../>子元素,每個<bean.../>子元素定義一個Bean,每個Bean對應Spring容器里的一個Java實例。
定義Bean時,通常需要指定兩個屬性。
?? id:確定該Bean的唯一標識符,容器對Bean管理、訪問,以及該Bean的依賴關系,都通過該屬性完成。Bean的id屬性在Spring容器中應該是唯一的。
?? class:指定該Bean的具體實現類,這里不能是接口。Spring容器必須知道創建Bean的實現類,而不能是接口。通常情況下,Spring會直接使用new關鍵字創建該Bean的實例,因此,這里必須提供Bean實現類的類名。
id屬性是容器中Bean的唯一標識,這個id屬性必須遵循XML文檔的id屬性規則,因此有一些特殊要求,例如不能以“/”等特殊符號作為屬性值。但在某些特殊時候,Bean的標識必須包含這些特殊符號,此時可以采用name屬性,用于指定Bean的別名,通過訪問Bean別名也可訪問Bean實例。
Spring容器集中管理Bean的實例化,Bean實例可以通過BeanFactory的getBean(String beanid)方法得到,BeanFactory變成簡單工廠模式里的工廠,程序只需要獲取BeanFactory引用,即可獲得Spring容器管理全部實例的引用。程序不需要與具體實例的實現過程耦合。大部分Java EE應用里,應用在啟動時,會自動創建Spring容器,組件之間直接以依賴注入的方式耦合,甚至無須主動訪問Spring容器本身。
當我們在配置文件中通過<bean id="xxx" class="lee.XxxClass"/>方法配置一個Bean時,這樣要求該Bean實現類必須有一個無參數的構造器,因此Spring
如果在配置文件中通過構造注入來創建Bean,配置代碼如下:
上面的粗體字代碼相當于讓Spring調用如下代碼:
bean1 = new lee.Test1("hello" , "23");??????? //①
由于Spring本身提供了功能強大類型轉換機制,因此如果lee.Test1只包含一個Test1(String , int)構造器,那么上面的粗體字配置文件相當于讓Spring執行如下代碼:
bean1 = new lee.Test1("hello" , 23);????????? //②
這就有了一個問題,如果lee.Test1類既有Test1(String ,String)構造器,又有Test1(String ,int)構造器,那么上面的粗體字配置文件到底讓Spring執行哪行代碼呢?答案是①號代碼,因為此時的配置還不夠明確:對于<constructor value="23"/>,Spring只能解析出一個"23"字符串,但它到底需要轉換為哪種數據類型——從配置文件中看不出來,只能是根據lee.Test1的構造器來嘗試轉換。
除了可以為<bean.../>元素指定一個id屬性之外,還可以為<bean.../>元素指定name屬性,用于為Bean實例指定別名。
<bean.../>元素的id屬性具有唯一性,而且是一個真正的XML ID屬性,因此其他XML元素在引用該id時,可以利用XML解析器的驗證功能。
由于XML規范規定了XML ID標識符必須由字母和數字組成,且只能以字母開頭,但在一些特殊情況下(例如與Struts1整合過程中),我們必須為控制器Bean指定特殊標識名,此時就必須為控制器Bean指定別名。
如果需要為Bean實例指定多個別名,可以在name屬性中使用逗號、冒號或者空格來分隔多個別名,后面通過任一別名即可訪問該Bean實例。
在一些極端的情況下,程序無法在定義Bean時就指定所有的別名,而是需要在其他地方為一個已經存在的Bean實例指定別名,則可使用<alias.../>元素來完成,該元素可指定如下兩個屬性。
?? name:該屬性指定一個Bean實例的標識名,表明將為該Bean實例指定別名。
?? alias:指定一個別名。
如以下代碼示例:
<alias name="person" alias="jack"/>
<alias name="jack" alias="jackee"/>
在默認情況下,當Spring創建ApplicationContext容器時,Spring會自動預初始化容器中所有的singleton實例,如果我們不想讓Spring容器預初始化某個singleton Bean,則可為該<bean.../>元素增加lazy-init屬性,指定該屬性為true,則Spring不會預初始化該Bean實例,如下面的配置文件所示。
<bean id="bean2" class="lee.Test2" lazy-init="true"/>
?
底層相當于調用了如下代碼:
?
下面給出包含兩個Bean定義的簡單配置文件。
<beans.../>元素上面所能指定的屬性都可以在每個<bean.../>子元素中指定——將屬性名去掉default即可。區別是:為<bean.../>元素指定這些屬性,只對特定Bean起作用;如果在<beans... />元素上指定這些屬性,這些屬性將會對<beans.../>包含的所有Bean都起作用。類似的是,當二者所指定的屬性不一致時,<bean.../>上指定的屬性會覆蓋<beans.../>上指定的屬性。
?
總結
- 上一篇: JVM编译时和运行时状态
- 下一篇: SCons: A software co