1. 程式人生 > 其它 >002SpringIOC002基於XML檔案配置Bean

002SpringIOC002基於XML檔案配置Bean

本文主要學習瞭如何通過XML配置的方式使用IOC容器。

1 管理普通Bean

1.1 建立物件

在配置檔案中使用bean標籤可以實現物件的建立。

配置如下:

1 <bean id="user" class="com.demo.spring.User"></bean>

預設使用的是類中的無參構造方法。

bean標籤中的屬性說明:

id屬性:表示物件的唯一標識。

class屬性:建立的物件所在的類的全路徑。

name屬性:和id屬性作用類似,可以使用特殊符號,但使用較少,早期使用的屬性。

1.2 注入屬性

1.2.1 通過setter方法注入屬性

這種方式需要使用property標籤,需要提供無參構造方法,以及定義屬性及其setter方法。

配置如下:

1 <bean id="user" class="com.demo.spring.User">
2   <property name="name" value="張三"></property>
3   <property name="age" value="22"></property>
4 </bean>

property標籤中的屬性說明:

name屬性:物件的屬性名稱。

value屬性:物件的屬性值。

1.2.2 通過構造器注入屬性

這種方式需要使用constructor-arg標籤,需要提供有參構造方法,以及定義屬性但不要求有setter方法。

配置如下:

1 <bean id="user" class="com.demo.spring.User">
2   <constructor-arg name="name" value="張三"></constructor-arg>
3   <constructor-arg name="age" value="22"></constructor-arg>
4 </bean>

constructor-arg標籤中的屬性說明:

name屬性:物件的屬性名稱。

value屬性:物件的屬性值。

type屬性:物件的屬性對應的型別,可省略。如果是基本型別就寫基本型別,如果是引用型別就寫全類名。

index屬性:按照構造器中屬性的順序注入屬性,很少用。構造器中屬性的順序從0開始。

1.2.3 通過名稱空間注入屬性

可以使用p名稱空間設定屬性,但較少使用。

這種方式需要使用p屬性,需要提供無參構造方法,以及定義屬性及其setter方法。

需要新增p名稱空間:

1 <beans xmlns="http://www.springframework.org/schema/beans"
2    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3    xmlns:p="http://www.springframework.org/schema/p"
4    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

配置如下:

1 <bean id="user" class="com.demo.spring.User" p:name="張三" p:age="22"></bean>

1.3 注入特殊屬性

1.3.1 注入Null值

配置如下:

1 <bean id="user" class="com.demo.spring.User">
2   <property name="name">
3     <null />
4   </property>
5 </bean>

1.3.2 注入包含特殊符號的值

配置如下:

1 <bean id="user" class="com.demo.spring.User">
2   <property name="name">
3     <value><![CDATA[張三]]></value>
4   </property>
5 </bean>

1.4 注入其他Bean物件

1.4.1 注入外部Bean

可以通過注入外部Bean的方式注入其他Bean物件。

配置如下:

1 <bean id="sz" class="com.demo.spring.Address">
2   <property name="province" value="廣東省"></property>
3   <property name="city" value="深圳市"></property>
4 </bean>
5 <bean id="user" class="com.demo.spring.User">
6   <property name="name" value="張三"></property>
7   <property name="address" ref="sz"></property>
8 </bean>

property標籤中的屬性說明:

ref屬性:外部Bean的id屬性。

1.4.2 注入內部的Bean

可以通過注入內部Bean的方式注入其他Bean物件。

配置如下:

1 <bean id="user" class="com.demo.spring.User">
2   <property name="name" value="張三"></property>
3   <property name="address">
4     <bean id="sz" class="com.demo.spring.Address">
5       <property name="province" value="廣東省"></property>
6       <property name="city" value="深圳市"></property>
7     </bean>
8   </property>
9 </bean>

1.4.3 注入級聯屬性

可以注入其他Bean的屬性,也就是注入級聯屬性。

需要提供Bean的getter方法以及Bean屬性的getter方法。

配置如下:

1 <property name="address.province" value="山東省"></property>

1.4.4 自動裝配

可以根據裝配方式自動引用其他Bean物件,不經常使用。

配置如下:

1 <bean id="sz" class="com.demo.spring.Address">
2   <property name="province" value="廣東省"></property>
3   <property name="city" value="深圳市"></property>
4 </bean>
5 <bean id="user" class="com.demo.spring.User" autowire="byName">
6   <!--<property name="address" ref="sz"></property>-->
7 </bean>

bean標籤中的屬性說明:

autowire屬性:外部Bean的引用方式。

autowire屬性有如下取值:

byName:根據屬性名進行裝配。這種方式會在配置檔案中查詢id和屬性名一樣的Bean,如果查到多個則報錯,如果沒有查到則設定null。

byType:根據屬性型別進行裝配。這種方式會在配置檔案中查詢和屬性型別一樣的Bean,如果查到多個則報錯,如果沒有查到則設定null。

constructor:根據構造器進行裝配。不常用。

default:不自動裝配,設定屬性為null。預設使用此種方式。

1.5 注入集合屬性

1.5.1 注入陣列屬性

需要定義陣列屬性並提供setter方法。

配置如下:

 1 <bean id="audi" class="com.demo.spring.Car">
 2   <property name="brand" value="奧迪"></property>
 3   <property name="color" value="白色"></property>
 4 </bean>
 5 <bean id="user" class="com.demo.spring.User">
 6   <property name="name" value="張三"></property>
 7   <property name="pets">
 8     <array>
 9       <value></value>
10       <value></value>
11     </array>
12   </property>
13   <property name="cars">
14     <array>
15       <ref bean="audi"></ref>
16       <bean id="volvo" class="com.demo.spring.Car">
17         <property name="brand" value="沃爾沃"></property>
18         <property name="color" value="黑色"></property>
19       </bean>
20     </array>
21   </property>
22 </bean>

標籤說明如下:

array標籤:定義陣列屬性。

value標籤:定義陣列中的基本型別和字串型別的成員。

ref標籤:定義陣列中的引用型別的成員,外部注入Bean。

bean標籤:定義陣列中的引用型別的成員,內部注入Bean。

1.5.2 注入List屬性

需要定義List屬性並提供setter方法。

配置如下:

 1 <bean id="audi" class="com.demo.spring.Car">
 2   <property name="brand" value="奧迪"></property>
 3   <property name="color" value="白色"></property>
 4 </bean>
 5 <bean id="user" class="com.demo.spring.User">
 6   <property name="name" value="張三"></property>
 7   <property name="pets">
 8     <list>
 9       <value></value>
10       <value></value>
11     </list>
12   </property>
13   <property name="cars">
14     <list>
15       <ref bean="audi"></ref>
16       <bean id="volvo" class="com.demo.spring.Car">
17         <property name="brand" value="沃爾沃"></property>
18         <property name="color" value="黑色"></property>
19       </bean>
20     </list>
21   </property>
22 </bean>

標籤說明如下:

list標籤:定義List屬性。

value標籤:定義List中的基本型別和字串型別的成員。

ref標籤:定義List中的引用型別的成員,外部注入Bean。

bean標籤:定義List中的引用型別的成員,內部注入Bean。

1.5.3 注入Set屬性

需要定義Set屬性並提供setter方法。

配置如下:

 1 <bean id="audi" class="com.demo.spring.Car">
 2   <property name="brand" value="奧迪"></property>
 3   <property name="color" value="白色"></property>
 4 </bean>
 5 <bean id="user" class="com.demo.spring.User">
 6   <property name="name" value="張三"></property>
 7   <property name="pets">
 8     <set>
 9       <value></value>
10       <value></value>
11     </set>
12   </property>
13   <property name="cars">
14     <set>
15       <ref bean="audi"></ref>
16       <bean id="volvo" class="com.demo.spring.Car">
17         <property name="brand" value="沃爾沃"></property>
18         <property name="color" value="黑色"></property>
19       </bean>
20     </set>
21   </property>
22 </bean>

標籤說明如下:

set標籤:定義Set屬性。

value標籤:定義Set中的基本型別和字串型別的成員。

ref標籤:定義Set中的引用型別的成員,外部注入Bean。

bean標籤:定義Set中的引用型別的成員,內部注入Bean。

1.5.4 注入Map屬性

需要定義Map屬性並提供setter方法。

配置如下:

 1 <bean id="audi" class="com.demo.spring.Car">
 2   <property name="brand" value="奧迪"></property>
 3   <property name="color" value="白色"></property>
 4 </bean>
 5 <bean id="mazda" class="com.demo.spring.Car">
 6   <property name="brand" value="馬自達"></property>
 7   <property name="color" value="紅色"></property>
 8 </bean>
 9 <bean id="user" class="com.demo.spring.User">
10   <property name="name" value="張三"></property>
11   <property name="pets">
12     <map>
13       <entry key="cat" value="貓"></entry>
14       <entry key="dog" value="狗"></entry>
15     </map>
16   </property>
17   <property name="cars">
18     <map>
19       <entry key="奧迪" value-ref="audi"></entry>
20       <entry key="馬自達" value-ref="mazda"></entry>
21       <entry key="沃爾沃">
22         <bean id="volvo" class="com.demo.spring.Car">
23           <property name="brand" value="沃爾沃"></property>
24           <property name="color" value="黑色"></property>
25         </bean>
26       </entry>
27     </map>
28   </property>
29 </bean>

標籤及屬性說明如下:

map標籤:定義Map屬性。

entry標籤:定義Map中的成員。

key屬性:定義Map中的基本型別和字串型別的key。

key-ref屬性:定義Map中的引用型別的key。

value屬性:定義Map中的基本型別和字串型別的value。

value-ref屬性:定義Map中的引用型別的value,外部注入Bean。

bean標籤:定義Map中的引用型別的value,內部注入Bean。

1.6 抽取集合屬性

使用util名稱空間可以將集合屬性抽取出來作為單獨的一個Bean。

需要新增util名稱空間:

1 <beans xmlns="http://www.springframework.org/schema/beans"
2    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3    xmlns:util="http://www.springframework.org/schema/util"
4    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
5              http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

配置如下:

 1 <util:map id="pets">
 2   <entry key="cat" value="貓"></entry>
 3   <entry key="dog" value="狗"></entry>
 4 </util:map>
 5 <util:map id="cars">
 6   <entry key="奧迪" value-ref="audi"></entry>
 7   <entry key="馬自達" value-ref="mazda"></entry>
 8   <entry key="沃爾沃">
 9     <bean id="volvo" class="com.demo.spring.Car">
10       <property name="brand" value="沃爾沃"></property>
11       <property name="color" value="黑色"></property>
12     </bean>
13   </entry>
14 </util:map>
15 <bean id="audi" class="com.demo.spring.Car">
16   <property name="brand" value="奧迪"></property>
17   <property name="color" value="白色"></property>
18 </bean>
19 <bean id="mazda" class="com.demo.spring.Car">
20   <property name="brand" value="馬自達"></property>
21   <property name="color" value="紅色"></property>
22 </bean>
23 <bean id="user" class="com.demo.spring.User">
24   <property name="name" value="張三"></property>
25   <property name="pets" ref="pets"></property>
26   <property name="cars" ref="cars"></property>
27 </bean>

2 管理工廠Bean

2.1 是什麼

Spring中有兩種型別的Bean,一種是普通Bean,另外一種是工廠Bean。

對於普通Bean來說,配置檔案中定義的Bean型別就是獲取Bean的返回型別。但對於工廠Bean來說,配置檔案中定義的Bean型別並不是獲取Bean的返回型別。

建立工廠Bean的步驟:

1)建立工廠類,實現FactoryBean介面並實現方法。

2)在實現的方法中定義返回的Bean型別。

2.2 使用

建立工廠類:

 1 public class Animal implements FactoryBean<Cat> {
 2   @Override
 3   public Cat getObject() throws Exception {
 4     return new Cat();
 5   }
 6   @Override
 7   public Class<?> getObjectType() {
 8     return null;
 9   }
10 }

在配置檔案中建立物件:

1 <bean id="cat" class="com.demo.spring.Animal"></bean>

測試:

1 @Test
2 public void testAdd() {
3   // 載入配置檔案
4   ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
5   // 獲取配置的物件
6   Cat cat = context.getBean("cat", Cat.class);
7   // 使用物件
8   System.out.println(cat);
9 }

3 Bean的作用域

3.1 預設

在IOC容器建立的時候,會將配置檔案中的物件全部建立並初始化。

預設建立的物件是單例項的,即多次獲取到的物件是同一個物件。

測試:

1 @Test
2 public void testAdd() {
3   ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
4   System.out.println(context.getBean("cat", Cat.class));
5   System.out.println(context.getBean("cat", Cat.class));
6 }

兩次獲取的地址相同,說明是同一物件,也表名預設情況下是單例的。

3.2 配置

在配置檔案中可以使用bean標籤的scope屬性修改建立物件的方式。

scope屬性的取值:

1 singleton:單例項,容器初始化時建立物件,預設的配置方式。
2 prototype:多例項,容器初始化時不建立物件,每次使用時建立物件,可以動態選擇物件。
3 request:在Web專案中,容器初始化時不建立物件,每個請求建立物件。
4 session:在Web專案中,容器初始化時不建立物件,每個會話建立物件。

配置多例項如下:

1 <bean id="cat" class="com.demo.spring.Animal" scope="prototype"></bean>

4 Bean的生命週期

4.1 是什麼

Bean的生命週期指的是Bean從建立到銷燬的全過程。

4.2 生命週期

4.2.1 順序

1)通過無參構造器建立Bean例項。

2)給Bean設定屬性值和Bean之間的引用。

3)執行Bean的初始化方法,需要設定方法。

4)獲取並使用Bean。

5)執行Bean的銷燬方法,需要設定方法,在手動銷燬容器時自動呼叫。

4.2.2 演示

建立類:

 1 public class User {
 2   public String name;
 3   public User() {
 4     System.out.println("Step1 通過無參構造器建立Bean例項");
 5   }
 6   public void setName(String name) {
 7     System.out.println("Step2 給Bean設定屬性值和Bean之間的引用");
 8     this.name = name;
 9   }
10   public void initMethod() {
11     System.out.println("Step3 執行Bean的初始化方法");
12   }
13   public void destroyMethod() {
14     System.out.println("Step5 執行Bean的銷燬方法");
15   }
16 }

配置檔案:

1 <bean id="user" class="com.demo.spring.User" init-method="initMethod" destroy-method="destroyMethod">
2   <property name="name" value="張三"></property>
3 </bean>

測試方法:

1 @Test
2 public void testAdd() {
3   ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
4   User user = context.getBean("user", User.class);
5   System.out.println("Step4 獲取並使用Bean");
6   System.out.println(user);
7   // Step5 手動銷燬容器,執行Bean的銷燬方法
8   context.close();
9 }

執行結果:

1 Step1 通過無參構造器建立Bean例項
2 Step2 給Bean設定屬性值和Bean之間的引用
3 Step3 執行Bean的初始化方法
4 Step4 獲取並使用Bean
5 com.demo.spring.User@5123a213
6 Step5 執行Bean的銷燬方法

4.3 後置處理器

4.3.1 定義

後置處理器會在執行Bean的初始化方法前後執行對應的方法,需要實現介面並在配置檔案中配置。

後置處理器會為當前配置檔案中的所有Bean例項都新增處理方法。

4.3.2 演示

建立後置處理器類:

 1 public class DemoBeanPost implements BeanPostProcessor {
 2   @Override
 3   public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
 4     System.out.println("Step3 執行Bean的初始化方法之前執行");
 5     return bean;
 6   }
 7   @Override
 8   public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
 9     System.out.println("Step3 執行Bean的初始化方法之後執行");
10     return bean;
11   }
12 }

配置檔案:

1 <bean id="demoBeanPost" class="com.demo.spring.DemoBeanPost"></bean>

執行結果:

1 Step1 通過無參構造器建立Bean例項
2 Step2 給Bean設定屬性值和Bean之間的引用
3 Step3 執行Bean的初始化方法之前執行
4 Step3 執行Bean的初始化方法
5 Step3 執行Bean的初始化方法之後執行
6 Step4 獲取並使用Bean
7 com.demo.spring.User@24b1d79b
8 Step5 執行Bean的銷燬方法

5 引入外部檔案

使用context名稱空間可以引入外部檔案,並使用其中的配置,多用於建立資料庫連線池。

需要新增context名稱空間:

1 <beans xmlns="http://www.springframework.org/schema/beans"
2    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3    xmlns:context="http://www.springframework.org/schema/context"
4    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
5              http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

配置如下:

1 <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
2 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
3   <property name="username" value="${mysql.username}"></property>
4   <property name="password" value="${mysql.password}"></property>
5   <property name="url" value="${mysql.url}"></property>
6   <property name="driverClassName" value="${mysql.driver}"></property>
7 </bean>