1. 程式人生 > >Spring中的Bean配置

Spring中的Bean配置

jdbc 子節點 drive 互訪 app 互訪問 style car 註意

IOC&DI概述

OPC(Inversion of Control):其思想是反轉資源獲取的方向。傳統的資源查找方式要求組件向容器發起請求查找資源。作為回應,容器適時的返回資源。而應用了IOC之後,則是容器主動地將資源推送給它所管理的組件,組件索要做的僅是選擇一種和氏的方式來接受資源。這種行為也被稱為查找的被動形式

DI(Dependency Injection)--IOC的另一種表述方式:即組件以一些預先定義好的方式(例如:setter方法)接受來自如容器的資源註入。相對於IOC而言,這種表述更直接

配置Bean

--配置形式:①基於XML文件的方式基②於註解的方式

--Bean的配置方式:通過全類名(反射)、通過工廠方法(靜態工廠方法&實例工廠方法)、FactoryBean

--IOC容器BeanFactory&ApplicationContext概述

依賴註入的方式:屬性註入;構造器註入

註入屬性值細節

class: javaBean的全類名,通過反射的方式在IOC容器中創建Bean,所以要求Bean中必須有無參數的構造器

id:標識容器中的Bean,id唯一.

<bean id="HelloSpring" class="cn.bdqn.spring.HelloSpring">

<property name="who" value="spring"></property>

</bean>

Spring 容器

在Spring IOC容器讀取Bean配置創建Bean實例之前,必須對它進行實例化,只有在容器實例後,才可以從IOC容器裏獲取Bean實例並使用

Spring 提供了兩種類型的IOC容器實現

① BeanFactory:IOC容器的基本實現

BeanFactory是Spring框架的基礎設施,面向Spring本身

② ApplicationContext: 提供了更多的高級特性,是BeanFactory的子接口.面向使用Spring框架的開發者,幾乎所有的應用場合都直接使用ApplicationContext而非底層的BeanFactory

無論使用何種方式,配置文件時相同

ApplicationContext的繼承架構:

技術分享

ApplicationContext的主要實現類

ClassPathXmlApplicationContext:從類路徑下加載配置文件

FileSystemXmlApplicationContext:從文件系統中加載配置文件

ApplicationContext的實現接口:

ConfigurableApplicationContext:是ApplicationContext的實現接口,新增兩個主要方法:refresh()和close(),讓ApplicationContext具有啟動刷新和關閉上下文的能力

ApplicationContext在初始化上下文時就實例化所有單例的Bean.

/*ApplicationContext代表IOC容器

ClassPathXmlApplicationContext是ApplicationContext的實現類,該實現類從類路徑下來加載配置文件*/

ApplicationContext context =

new ClassPathXmlApplicationContext("applicationContext.xml");

/* 從IOC容器中獲取Bean實例 "HelloSpring"是我們applicationContext.xml中配置的id屬性的值利用id定位到IOC中的Bean */

HelloSpring bean = (HelloSpring)context.getBean("HelloSpring");

依賴註入的方式:

①屬性註入

屬性註入即通過setter方法註入Bean的屬性值或依賴的對象,

屬性註入使用<property>元素,使用name屬性指定Bean的屬性名稱,value屬性或<value>子節點指定屬性值

屬性主圖是實際應用中最常見的註入方式

實例:

<!--

配置bean

class javaBean的全類名,通過反射的方式在IOC容器中創建Bean,所以要求Bean中必須有無參數的構造器

id:標識容器中的Bean,id唯一.

-->

<bean id="HelloSpring" class="cn.bdqn.spring.HelloSpring">

<property name="who" value="spring"></property>

</bean>

②構造器註入

<constructor-arg> 代表我們構造器中的參數,一個標簽僅能為我們構造器中的一個參數賦值

實例:

我們編寫的javaBean代碼為:

public class Person {

private String name;

private String country;

private int age;

//工資

private double salary;

public Person(String name, String country, double salary) {

super();

this.name = name;

this.country = country;

this.salary = salary;

}

public Person(String name, String country, int age) {

super();

this.name = name;

this.country = country;

this.age = age;

}

配置文件如下:

<bean id="p1" class="cn.bdqn.spring.Person">

<constructor-arg value="zhangsna" ></constructor-arg>

<constructor-arg value="zhongguo" ></constructor-arg>

<constructor-arg value="23 " ></constructor-arg>

</bean>

<bean id="p2" class="cn.bdqn.spring.Person">

<constructor-arg value="lisi"></constructor-arg>

<constructor-arg value="meiguo"></constructor-arg>

<constructor-arg value="4000"></constructor-arg>

</bean>

最後程序運行後出現以下結果:

技術分享

這個結果顯然和我們預期的不一致

程序運行時會將我們的給定的參數與javaBean中的構造方法進行匹配,當匹配成功時選擇對應的構造器進行執行,我們在配置文件中將salary屬性的值設置為整數時,jvm就會將這個配置與我們構造器中的參數為int型的構造器進行匹配,如果不存在int型參數的構造器,才會正確執行

也就是說,我們程序中如果將以下構造器刪除,程序便會將int自動轉換為double進行匹配

public Person(String name, String country, int age) {

super();

this.name = name;

this.country = country;

this.age = age;

}

如果我們想保留兩個構造器,並且讓程序正確執行的話,我們可以在配置文件中的constructor-arg標簽中添加type屬性.為value指定一個類型:

<bean id="p1" class="cn.bdqn.spring.Person">

<constructor-arg value="zhangsna" ></constructor-arg>

<constructor-arg value="zhongguo" ></constructor-arg>

<constructor-arg value="23 " type="int" ></constructor-arg>

</bean>

<bean id="p2" class="cn.bdqn.spring.Person">

<constructor-arg value="lisi"></constructor-arg>

<constructor-arg value="meiguo"></constructor-arg>

<constructor-arg value="4000" type="double"></constructor-arg>

</bean>

程序便會正確執行

在constructor-arg標簽中還有index屬性,該屬性的屬性值從0開始,給構造器中指定位置的參數賦值.

③工廠方法註入(很少使用,不推薦)

註入屬性值的詳解

① 字面值

可以通過value元素標簽或value屬性進行入

<constructor-arg value="lisi"></constructor-arg>

可用如下代碼進行替換

<constructor-arg>

<value>lili</value>

</constructor-arg>

基本數據類型及其封裝類、String等類型都可以采用字面值註入的方式,若字面值中包含特殊字符,可以使用<![CDATA[值]]>把字面值包裹起來

例如:我們要給屬性賦一個郵箱

<constructor-arg>

<value><![CDATA[[email protected]]]></value>

</constructor-arg>

引用其它javaBean

組成應用程序的Bean經常需要相互寫作以完成應用程序的功能,要使用Bean能夠相互訪問,就必須在Bean配置文件中指定對Bean的引用

Bean配置的形式:

① 使用外部Bean進行配置

在Bean的配中可以通過<ref>元素或ref屬性為Bean的屬性或構造器參數指定對Bean的引用。

實例1:使用外部bean和ref屬性進行配置

</bean>

<bean id="car1" class="cn.bdqn.spring.Car">

<property name="brand" value="ford"></property>

<property name="price" value="230000"></property>

</bean>

<bean id="p3" class="cn.bdqn.spring.Person">

<property name="name" value="bell"></property>

<property name="age" value="23"></property>

<property name="car" ref="car1"></property>

</bean>

實例2:使用外部bean和ref節點進行配置

<bean id="car1" class="cn.bdqn.spring.Car">

<property name="brand" value="ford"></property>

<property name="price" value="230000"></property>

</bean>

<bean id="p3" class="cn.bdqn.spring.Person">

<property name="name" value="bell"></property>

<property name="age" value="23"></property>

<property name="car">

<ref bean="car1" />

</property>

</bean>

也可以使用構造器的方式進行配置,其配置操作也不經相同

② 使用內部Bean進行配置

也可以在屬性或構造器中包含Bean的聲明,這樣的Bean稱為內部Bean

實例:

<bean id="p3" class="cn.bdqn.spring.Person">

<property name="name" value="bell"></property>

<property name="age" value="23"></property>

<property name="car">

<bean id="car1" class="cn.bdqn.spring.Car">

<property name="brand" value="ford"></property>

<property name="price" value="230000"></property>

</bean>

</property>

</bean>

內部Bean和外部Bean的區別:內部Bean不能被外部所訪問,僅供所在Bean的引用

註入參數詳解:null值和級聯屬性

可以使用專用的</null>標簽為Bean的字符串或其他對象類型的屬性註入null值(意義不大,因為引用類型的屬性的默認值就是null)

和Strus、Hibernate 等框架一樣,Spring支持級聯屬性的配置

級聯屬性實例:

<bean id="p2" class="cn.bdqn.spring.Person">

<!-- <constructor-arg value="lisi"></constructor-arg> -->

<constructor-arg>

<value><![CDATA[[email protected]]]></value>

</constructor-arg>

<constructor-arg value="meiguo"></constructor-arg>

<constructor-arg value="4000" type="double"></constructor-arg>

<constructor-arg ref="car"></constructor-arg>

<property name="car.brand" value="changan"></property>

<property name="car.price" value="100000"></property>

</bean>

<bean id="car" class="cn.bdqn.spring.Car"></bean>

註意:為級聯屬性賦值,屬性需要先初始化後才可以為級聯屬性賦值。否則會報異常

集合屬性:

在Spring中可以通過一組內置的xml標簽(例如:<list>、<set>或<map>)來配置集合屬性。

① 配置java.util.List類型的屬性

需要指定<list>標簽,在標簽裏包含一些元素,這些標簽可以通過<value>指定簡單的常量值,通過<ref>指定對其他Bean的引用,通過<bean>指定內置Bean的定義,通過<null/>指定空元素,甚至可以內嵌其他集合。

② 數組的定義和List一樣,都是用<list>

③ 配置java.util.Set需要使用<set>標簽,定義元素的方法與List一樣

實例:

模擬,一人有多輛車

<bean id="car1" class="cn.bdqn.spring.Car">

<property name="brand" value="ford"></property>

<property name="price" value="100000"></property>

</bean>

<bean id="car2" class="cn.bdqn.spring.Car">

<property name="brand" value="寶馬"></property>

<property name="price" value="200000"></property>

</bean>

<bean id="car3" class="cn.bdqn.spring.Car">

<property name="brand" value="奔馳"></property>

<property name="price" value="300000"></property>

</bean>

<bean id="person" class="cn.bdqn.spring.Person">

<property name="name" value="baoqiang"></property>

<property name="age" value="23"></property>

<property name="car">

<list>

<ref bean="car1" />

<ref bean="car2" />

<ref bean="car3" />

</list>

</property>

</bean>

也可以寫成內部Bean的樣式

<bean id="person" class="cn.bdqn.spring.Person">

<property name="name" value="baoqiang"></property>

<property name="age" value="23"></property>

<property name="car">

<list>

<bean id="car1" class="cn.bdqn.spring.Car">

<property name="brand" value="ford"></property>

<property name="price" value="100000"></property>

</bean>

<bean id="car2" class="cn.bdqn.spring.Car">

<property name="brand" value="寶馬"></property>

<property name="price" value="200000"></property>

</bean>

<bean id="car3" class="cn.bdqn.spring.Car">

<property name="brand" value="奔馳"></property>

<property name="price" value="300000"></property>

</bean>

</list>

</property>

</bean>

④ Java.util.Map通過<map>標簽定義

<map>標簽裏可以使用多個entry作為子標簽,每個條目包含一個鍵和一個值

必須在<key>標簽裏定義鍵

因為鍵和值的類型沒有限制,所以可以自由地為它們指定<value>,<ref>,<bean>,<null>元素

可以將Map的鍵和值作為<entry>的屬性定義:簡單敞亮可以使用key和value來定義;Bean引用通過key-ref和value-ref屬性定義

實例:模擬一人有多量車(使用外部Bean的方式)

<bean id="car1" class="cn.bdqn.spring.Car">

<property name="brand" value="ford"></property>

<property name="price" value="100000"></property>

</bean>

<bean id="car2" class="cn.bdqn.spring.Car">

<property name="brand" value="寶馬"></property>

<property name="price" value="200000"></property>

</bean>

<bean id="car3" class="cn.bdqn.spring.Car">

<property name="brand" value="奔馳"></property>

<property name="price" value="300000"></property>

</bean>

<!-- 配置Map屬性值 -->

<bean id="newPerson" class="cn.bdqn.spring.Person">

<property name="name" value="jielun"></property>

<property name="age" value="32"></property>

<property name="car">

<map>

<entry key="AA" value-ref="car1"></entry>

<entry key="BB" value-ref="car2"></entry>

<entry key="CC" value-ref="car3"></entry>

</map>

</property>

</bean>

Map中key的值由我們指定,value是引用的實例

⑤使用<props>定義java.util.Properties

該標簽使用多個<prop>作為子標簽,每個<prop>標簽必須定義key屬性。

實例:

<bean id="mysql" class="cn.bdqn.spring.DateSource">

<property name="properties">

<props>

<prop key="userName">admin</prop>

<prop key="password">admin</prop>

<prop key="url">jdbc:mysql://test</prop>

<prop key="driver"> com.mysql.jdbc.Driver</prop>

</props>

</property>

</bean>

⑥使用utility scheme定義集合

使用基本的集合標簽定義集合時,不能將集合作為獨立的Bean定義,導致其他Bean無法引用該集合,所以無法再不同的Bean之間共享集合

可以使用util schema裏的集合標簽定義獨立的集合Bean。需要註意的是,必須在<beans>根元素裏添加util schema定義

實例:模擬一人有多輛車

首先需要導入util命名空間

如下圖:

技術分享

代碼如下:

<!-- 配置獨立的集合bean,以供多個bean進行引用.需要導入util命名空間 -->

<bean id="car1" class="cn.bdqn.spring.Car">

<property name="brand" value="ford"></property>

<property name="price" value="100000"></property>

</bean>

<bean id="car2" class="cn.bdqn.spring.Car">

<property name="brand" value="寶馬"></property>

<property name="price" value="200000"></property>

</bean>

<bean id="car3" class="cn.bdqn.spring.Car">

<property name="brand" value="奔馳"></property>

<property name="price" value="300000"></property>

</bean>

<util:list id="cars">

<ref bean="car1" />

<ref bean="car2"/>

<ref bean="car3"/>

</util:list>

<bean id="p1" class="cn.bdqn.spring.Person">

<property name="name" value="xiaozhao"></property>

<property name="age" value="25"></property>

<property name="car" ref="cars"></property>

</bean>

⑦P命名空間的使用

我們還可以使用P命名空間對bean進行配置

為來簡化XML文件的配置,越來越多的XML文件采用屬性而非子元素配置信息

Spring從2.5版本開始引入一個新的P命名空間,可以通過<bean>元素屬性的方式配置Bean的屬性。

使用P命名空間後,基於XML的配置方式將進一步簡化

實例:模擬一人有多輛車

首先先引入P命名空間

如下圖

技術分享

使用util和P命名空間代碼:

<bean id="car1" class="cn.bdqn.spring.Car">

<property name="brand" value="ford"></property>

<property name="price" value="100000"></property>

</bean>

<bean id="car2" class="cn.bdqn.spring.Car">

<property name="brand" value="寶馬"></property>

<property name="price" value="200000"></property>

</bean>

<bean id="car3" class="cn.bdqn.spring.Car">

<property name="brand" value="奔馳"></property>

<property name="price" value="300000"></property>

</bean>

<util:list id="cars">

<ref bean="car1" />

<ref bean="car2" />

<ref bean="car3" />

</util:list>

<bean id="person" class="cn.bdqn.spring.Person" p:name="xiaowang"

p:age="23" p:car-ref="cars">

</bean>

Spring中的Bean配置