002SpringIOC002基於XML檔案配置Bean
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>