Spring学习(五)bean装配详解之 【XML方式配置】
本文借鑒:Spring學習(特此感謝!)
一、配置Bean的方式及選擇
配置方式
- 在 XML 文件中顯式配置
- 在 Java 的接口和類中實現配置
- 隱式 Bean 的發現機制和自動裝配原則
方式選擇的原則
最優先:通過隱式 Bean 的發現機制和自動裝配的原則。
基于約定優于配置的原則,這種方式應該是最優先的
- 好處:減少程序開發者的決定權,簡單又不失靈活。
其次:Java 接口和類中配置實現配置
在沒有辦法使用自動裝配原則的情況下應該優先考慮此類方法
- 好處:避免 XML 配置的泛濫,也更為容易。
- 典型場景:一個父類有多個子類,比如學生類有兩個子類,一個男學生類和女學生類,通過 IoC 容器初始化一個學生類,容器將無法知道使用哪個子類去初始化,這個時候可以使用 Java 的注解配置去指定。
最后:XML 方式配置
在上述方法都無法使用的情況下,那么也只能選擇 XML 配置的方式。
好處:簡單易懂(當然,特別是對于初學者)
典型場景:當使用第三方類的時候,有些類并不是我們開發的,我們無法修改里面的代碼,這個時候就通過 XML 的方式配置使用了。
二、通過 XML 配置裝配 Bean
1、XML配置前言
使用 XML 裝配 Bean 需要定義對應的 XML,這里需要引入對應的 XML 模式(XSD)文件,這些文件會定義配置 Spring Bean 的一些元素,當我們在 IDEA 中創建 XML 文件時,會有友好的提示:
一個簡單的 XML 配置文件如下:
<?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.xsd"></beans>這就只是一個格式文件,引入了一個 beans 的定義,引入了 xsd 文件,它是一個根元素,這樣它所定義的元素將可以定義對應的 Spring Bean。
2、裝配簡易值
先來一個最簡單的裝配:
<bean id="c" class="pojo.Category"><property name="name" value="測試" /> </bean>簡單解釋一下:
?id?屬性是 Spring 能找到當前 Bean 的一個依賴的編號,遵守 XML 語法的 ID 唯一性約束。必須以字母開頭,可以使用字母、數字、連字符、下劃線、句號、冒號,不能以/開頭。
???name?屬性也可以定義 bean 元素的名稱,能以逗號或空格隔開起多個別名,并且可以使用很多的特殊字符,比如在 Spring 和 Spring MVC 的整合中,就得使用?name?屬性來定義 bean 的名稱,并且使用?/開頭。
?class?屬性顯然就是一個類的全限定名
?property?元素是定義類的屬性,其中的?name?屬性定義的是屬性的名稱,而?value?是它的值。
?
PS:?從 Spring 3.1 開始,id?屬性也可以是 String 類型了,也就是說?id?屬性也可以使用?/?開頭,而 bean 元素的 id 的唯一性由容器負責檢查。
PS:如果?id?和?name?屬性都沒有聲明的話,那么 Spring 將會采用?“全限定名#{number}”?的格式生成編號。 例如這里,如果沒有聲明 “id="c"” 的話,那么 Spring 為其生成的編號就是是“pojo.Category#0”,當它第二次聲明沒有?id?屬性的 Bean 時,編號就是 “pojo.Category#1”,以此類推。
這樣的定義很簡單,但是有時候需要注入一些自定義的類,比如之前飲品店的例子,JuickMaker 需要用戶提供原料信息才能完成 juice 的制作:
<!-- 配置 srouce 原料 --> <bean name="source" class="pojo.Source"><property name="fruit" value="橙子"/><property name="sugar" value="多糖"/><property name="size" value="超大杯"/> </bean><bean name="juickMaker" class="pojo.JuiceMaker"><!-- 注入上面配置的id為srouce的Srouce對象 --><property name="source" ref="source"/> </bean>這里先定義了一個?name?為 source 的 Bean,然后再制造器中通過?ref?屬性去引用對應的 Bean,而 source 正是之前定義的 Bean 的?name?,這樣就可以相互引用了。
?ref 引用對象
3、裝配集合
有些時候我們需要裝配一些復雜的東西,比如 Set、Map、List、Array 和 Properties 等,為此我們在 Packge【pojo】下新建一個 ComplexAssembly 類:
package pojo;import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set;public class ComplexAssembly {private Long id;private List<String> list;private Map<String, String> map;private Properties properties;private Set<String> set;private String[] array;/* setter and getter */ }這個 Bean 沒有任何的實際意義,只是為了介紹如何裝配這些常用的集合類:
<bean id="complexAssembly" class="pojo.ComplexAssembly"><!-- 裝配Long類型的id --><property name="id" value="1"/><!-- 裝配List類型的list --><property name="list"><list><value>value-list-1</value><value>value-list-2</value><value>value-list-3</value></list></property><!-- 裝配Map類型的map --><property name="map"><map><entry key="key1" value="value-key-1"/><entry key="key2" value="value-key-2"/><entry key="key3" value="value-key-2"/></map></property><!-- 裝配Properties類型的properties --><property name="properties"><props><prop key="prop1">value-prop-1</prop><prop key="prop2">value-prop-2</prop><prop key="prop3">value-prop-3</prop></props></property><!-- 裝配Set類型的set --><property name="set"><set><value>value-set-1</value><value>value-set-2</value><value>value-set-3</value></set></property><!-- 裝配String[]類型的array --><property name="array"><array><value>value-array-1</value><value>value-array-2</value><value>value-array-3</value></array></property> </bean>總結:
- List 屬性為對應的 <list> 元素進行裝配,然后通過多個 <value> 元素設值
- Map 屬性為對應的 <map> 元素進行裝配,然后通過多個 <entry> 元素設值,只是 entry 包含一個鍵值對(key-value)的設置
- Properties 屬性為對應的 <properties> 元素進行裝配,通過多個 <property> 元素設值,只是 properties 元素有一個必填屬性 key ,然后可以設置值
- Set 屬性為對應的 <set> 元素進行裝配,然后通過多個 <value> 元素設值
- 對于數組而言,可以使用 <array> 設置值,然后通過多個 <value> 元素設值。
上面看到了對簡單 String 類型的各個集合的裝載,但是有些時候可能需要更為復雜的裝載,比如一個 List 可以是一個系列類的對象,為此需要定義注入的相關信息,其實跟上面的配置沒什么兩樣,只不過加入了 ref 這一個屬性而已。
集合注入總結:
- List 屬性使用 <list> 元素定義注入,使用多個 <ref> 元素的 Bean 屬性去引用之前定義好的 Bean
- Map 屬性使用?<map>?元素定義注入,使用多個?<entry>?元素的?key-ref?屬性去引用之前定義好的 Bean 作為鍵,而用?value-ref?屬性引用之前定義好的 Bean 作為值
- Set 屬性使用?<set>?元素定義注入,使用多個?<ref>?元素的?bean?去引用之前定義好的 Bean
4、命名空間裝配
除了上述的配置之外, Spring 還提供了對應的命名空間的定義,只是在使用命名空間的時候要先引入對應的命名空間和 XML 模式(XSD)文件。
c-命名空間(constructor,配置構造器的參數)
c-命名空間是在 Spring 3.0 中引入的,它是在 XML 中更為簡潔地描述構造器參數的方式,要使用它的話,必須要在 XML 的頂部聲明其模式:
PS:是通過構造器參數的方式
現在假設我們現在有這么一個類:
package pojo;public class Student {int id;String name;public Student(int id, String name) {this.id = id;this.name = name;}// setter and getter }在 c-命名空間和模式聲明之后,我們就可以使用它來聲明構造器參數了:
<!-- 引入 c-命名空間之前 --> <bean name="student1" class="pojo.Student"><constructor-arg name="id" value="1" /><constructor-arg name="name" value="學生1"/> </bean><!-- 引入 c-命名空間之后 --> <bean name="student2" class="pojo.Student"c:id="2" c:name="學生2"/>c-命名空間屬性名以 “c:” 開頭,也就是命名空間的前綴。接下來就是要裝配的構造器參數名,在此之后如果需要注入對象的話則要跟上?-ref(如c:card-ref="idCard1",則對 card 這個構造器參數注入之前配置的名為 idCard1 的 bean)
很顯然,使用 c-命名空間屬性要比使用?<constructor-arg>?元素精簡,并且會直接引用構造器之中參數的名稱,這有利于我們使用的安全性。
我們有另外一種替代方式:
<bean name="student2" class="pojo.Student" c:_0="3" c:_1="學生3"/>我們將參數的名稱替換成了 “0” 和 “1” ,也就是參數的索引。因為在 XML 中不允許數字作為屬性的第一個字符,因此必須要添加一個下劃線來作為前綴。
p-命名空間(property,配置構造器的參數)
c-命名空間通過構造器注入的方式來配置 bean,p-命名空間則是用setter的注入方式來配置 bean ,同樣的,我們需要引入聲明:
? 然后我們就可以通過 p-命名空間來設置屬性:
<!-- 引入p-命名空間之前 --> <bean name="student1" class="pojo.Student"><property name="id" value="1" /><property name="name" value="學生1"/> </bean><!-- 引入p-命名空間之后 --> <bean name="student2" class="pojo.Student" p:id="2" p:name="學生2"/>我們需要先刪掉 Student 類中的構造函數,不然 XML 約束會提示我們配置?<constructor-arg>?元素。
同樣的,如果屬性需要注入其他 Bean 的話也可以在后面跟上?-ref:
<bean name="student2" class="pojo.Student" p:id="2" p:name="學生2" p:cdCard-ref="cdCard1"/>util-命名空間
工具類的命名空間,可以簡化集合類元素的配置,同樣的我們需要引入其聲明(無需擔心怎么聲明的問題,IDEA會有很友好的提示):
我們來看看引入前后的變化:?
<!-- 引入util-命名空間之前 --> <property name="list"><list><ref bean="bean1"/><ref bean="bean2"/></list> </property><!-- 引入util-命名空間之后 --> <util:list id="list"><ref bean="bean1"/><ref bean="bean2"/> </util:list>下表提供了 util-命名空間提供的所有元素:
5、引入其他配置文件
在實際開發中,隨著應用程序規模的增加,系統中?<bean>?元素配置的數量也會大大增加,導致 applicationContext.xml 配置文件變得非常臃腫難以維護。
解決方案
讓 applicationContext.xml 文件包含其他配置文件即可 使用 <import> 元素引入其他配置文件
【1】在【src】文件下新建一個 bean.xml 文件,寫好基礎的約束,把 applicationContext.xml 文件中配置的 <bean> 元素復制進去
【2】在 applicationContext.xml 文件中寫入
<import resource="bean.xml" />【3】運行測試代碼,仍然能正確獲取到 bean
轉載于:https://www.cnblogs.com/riches/p/11520090.html
總結
以上是生活随笔為你收集整理的Spring学习(五)bean装配详解之 【XML方式配置】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 终端链接操作redis
- 下一篇: SQLite.NET.0.17 的离奇之