如何將本身開發的Bean裝配到Spring IoC容器中。在大部分場景下,咱們都會使用ApplicationContext的具體實現類,由於對應的Spring IoC容器功能相對強大。而在Spring中提供了3種方法進行配置:
•在XML中顯示配置。
•在Java的接口和類中實現配置。
•隱式Bean的發現機制和自動裝配原則。spring
在現實的工做中,這3種方式都會被用到,而且在學習和工做中經常混合使用,須要明確3種方式的優先級,也就是咱們應該怎麼選擇使用哪一種方式去把Bean發佈到Spring IoC容器中。如下是的建議:
(1)基於約定優於配置的原則,最優先的應該是經過隱式Bean的發現機制和自動裝配的原則。這樣的好處是減小程序開發者的決定權,簡單又不失靈活。
(2)在沒有辦法使用自動裝配原則的狀況下應該優先考慮Java接口和類中實現配置,這樣的好處是避免XML配置的泛濫,也更爲容易。這種場景典型的例子是一個父類有多個子類,好比學生類有兩個子類:男學生類和女學生類,經過IoC容器初始化一個學生類,容器將沒法知道使用哪一個子類去初始化,這個時候可使用Java的註解配置去指定。
(3)在上述方法都沒法使用的狀況下,那麼只能選擇XML去配置Spring IoC容器。因爲現實工做中經常用到第三方的類庫,有些類並非咱們開發的,咱們沒法修改裏面的代碼,這個時候就經過XML的方式配置使用了。
通俗來說,當配置的類是你自身正在開發的工程,那麼應該考慮Java配置爲主,而Java配置又分爲自動裝配和Bean名稱配置。在沒有歧義的基礎上,優先使用自動裝配,這樣就能夠減小大量的XML配置。若是所需配置的類並非你的工程開發的,那麼建議使用XML的方式。數組
使用XML裝配Bean須要定義對應的XML,這裏須要引入對應的XML模式(XSD)文件,這些文件會定義配置SpringBean的一些元素,一個簡單的配置以下:學習
<?xml version='1.0' encoding='UTF-8' ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <!--Spring Bean配置代碼--> </beans>
在上述代碼中引入了一個beans的定義,它是一個根元素,而XSD文件也被引入了,這樣它所定義的元素將能夠定義對應的Spring Bean。ui
代碼清單:簡易XML裝配beanspa
<bean id="role2" class="com.ssm.chapter9.pojo.Role"> <property name="id" value="1"/> <property name="roleName" value="高級工程師"/> <property name="note" value="重要人員"/> </bean>
這是一個簡易的配置,簡單解釋一下:
•id屬性是Spring找到的這個Bean的編號,不過id不是一個必需的屬性,若是沒有聲明它,那麼Spring將會採用「全限定名#{number}」的格式生成編號。若是隻聲明一個這樣的類,而沒有聲明id="role2",那麼Spring爲其生成的編號就是「com.ssm.chapter9.pojo.Role#0」。當它第二次聲明沒有id屬性的Bean時,編號就是「com.ssm.chap-ter9.pojo.Role#1」,可是通常咱們都會選擇本身定義id,由於自動生成的id會比較煩瑣。
•class顯然是一個類全限定名。
•property元素是定義類的屬性,其中name屬性定義的是屬性名稱,而value是其值。code
這樣的定義很簡單,可是有時候須要注入一些自定義的類,好比以前的果汁製造器例子,它須要原料信息和飲品店共同完成,因而可能要先定義原料的信息,而後在製造器中引用原料,如代碼清單所示。xml
<bean id="source" class="com.ssm.chapter9.pojo.Source"> <property name="fruit" value="橙汁"/> <property name="sugar" value="少糖"/> <property name="size" value="3"/> </bean> <bean id="juiceMaker2" class="com.ssm.chapter9.pojo.JuiceMaker2"> <property name="beverageShop" value="貢茶"/> <property name="source" ref="source"/> </bean>
這裏先定義了一個id爲source的Bean,而後在製造器中經過ref屬性去引用對應的Bean,而source正是以前定義的Bean的id,這樣就能夠相互引用了。對象
有些時候要作一些複雜的裝配工做,好比Set、Map、List、Array和Properties等。爲了介紹它們,先定義個Bean,如代碼清單所示。blog
public class ComplexAssembly { private Long id; private List<String> list; private Map<String, String> map; private Properties props; private Set<String> set; private String[] array; /****setter and getter ****/ }
這個Bean沒有任何的業務含義,只是爲了介紹如何裝配這些經常使用的集合類,爲此能夠如同代碼清單10-9這樣裝配這些屬性。接口
代碼清單:裝配集合類spring-cfg.xml
<bean id="complexAssembly" class="com.ssm.chapter10.pojo.ComplexAssembly"> <property name="id" value="1"/> <property name="list"> <list> <value>value-list-1</value> <value>value-list-2</value> <value>value-list-3</value> </list> </property> <property name="map"> <map> <entry key="key1" value="value-key-1"/> <entry key="key2" value="value-key-2"/> <entry key="key3" value="value-key-3"/> </map> </property> <property name="props"> <props> <prop key="prop1">value-prop-1</prop> <prop key="prop2">value-prop-2</prop> <prop key="prop3">value-prop-3</prop> </props> </property> <property name="set"> <set> <value>value-set-1</value> <value>value-set-2</value> <value>value-set-3</value> </set> </property> <property name="array"> <array> <value>value-array-1</value> <value>value-array-2</value> <value>value-array-3</value> </array> </property> </bean>
固然這裏的裝配主要集中在比較簡單的String類型上,其主要的目的是告訴你們如何裝配一些簡易的數據到集合中。
•List屬性爲對應的<list>元素進行裝配,而後經過多個<value>元素設值。
•Map屬性爲對應的<mali>元素進行裝配,而後經過多個<entry>元素設值,只是entry包含一個鍵(key)和一個值(value)的設置。
•Properties屬性,爲對應的<properties>元素進行裝配,經過多個<property>元素設置,只是property元素有一個必填屬性key,而後能夠設置值。
•Set屬性爲對應的<set>元素進行裝配,而後經過多個<value>元素設值。
•對於數組而言,可使用<array>設置值,而後經過多個<value>元素設值。
ApplicationContext ctx = new ClassPathXmlApplicationContext("ssm/chapter10/spring-cfg.xml"); ComplexAssembly userRoleAssembly = (ComplexAssembly) ctx.getBean("userRoleAssembly"); System.out.println(userRoleAssembly.toString());
從上面能夠看到對字符串的各個集合的裝載,可是有些時候可能須要更爲複雜的裝載,好比一個List能夠是一個系列類的對象,又如一個Map集合類,鍵能夠是一個類對象,而值也要是一個類對象,這些也是Java中經常能夠看到的。
public class Role { private Long id; private String roleName; private String note; } public class User { private Long id; private String userName; private String note; } public class UserRoleAssembly { private Long id; private List<Role> list; private Map<Role, User> map; private Set<Role> set; }
spring-cfg2.xml:
<bean id="role1" class="com.ssm.chapter10.pojo.Role"> <property name="id" value="1"/> <property name="roleName" value="role_name_1"/> <property name="note" value="role_note_1"/> </bean> <bean id="role2" class="com.ssm.chapter10.pojo.Role"> <property name="id" value="2"/> <property name="roleName" value="role_name_2"/> <property name="note" value="role_note_2"/> </bean> <bean id="user1" class="com.ssm.chapter10.pojo.User"> <property name="id" value="1"/> <property name="userName" value="user_name_1"/> <property name="note" value="role_note_1"/> </bean> <bean id="user2" class="com.ssm.chapter10.pojo.User"> <property name="id" value="2"/> <property name="userName" value="user_name_2"/> <property name="note" value="role_note_1"/> </bean> <bean id="userRoleAssembly" class="com.ssm.chapter10.pojo.UserRoleAssembly"> <property name="id" value="1"/> <property name="list"> <list> <ref bean="role1"/> <ref bean="role2"/> </list> </property> <property name="map"> <map> <entry key-ref="role1" value-ref="user1"/> <entry key-ref="role2" value-ref="user2"/> </map> </property> <property name="set"> <set> <ref bean="role1"/> <ref bean="role2"/> </set> </property> </bean>
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("ssm/chapter10/spring-cfg2.xml"); UserRoleAssembly userRoleAssembly = (UserRoleAssembly) ctx.getBean("userRoleAssembly"); System.out.println(userRoleAssembly.toString());
除上述的配置以外,Spring還提供了對應的命名空間的定義,只是在使用命名空間的時候要先引入對應的命名空間和XML模式(XSD)文件。
<bean id="role1" class="com.ssm.chapter10.pojo.Role" c:_0="1" c:_1="role_name_1" c:_2="role_note_1"/> <bean id="role2" class="com.ssm.chapter10.pojo.Role" p:id="2" p:roleName="role_name_2" p:note="role_note_2"/> <bean id="user1" class="com.ssm.chapter10.pojo.User" p:id="1" p:userName="role_name_1" p:note="user_note_1"/> <bean id="user2" class="com.ssm.chapter10.pojo.User" p:id="2" p:userName="role_name_2" p:note="user_note_2"/> <util:list id="list"> <ref bean="role1"/> <ref bean="role2"/> </util:list> <util:map id="map"> <entry key-ref="role1" value-ref="user1"/> <entry key-ref="role2" value-ref="user2"/> </util:map> <util:set id="set"> <ref bean="role1"/> <ref bean="role2"/> </util:set> <bean id="userRoleAssembly" class="com.ssm.chapter10.pojo.UserRoleAssembly" p:id="1" p:list-ref="list" p:map-ref="map" p:set-ref="set"/>
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("ssm/chapter10/spring-cfg3.xml"); UserRoleAssembly userRoleAssembly = (UserRoleAssembly) ctx.getBean("userRoleAssembly"); System.out.println(userRoleAssembly.toString());