天天看點

【Spring4.0】 Spring中的Bean配置

注意!!

此篇博文和上一篇博文有一些關聯,如已經建立好的各種類的位置,如果對于類的位置不清楚請看上一篇博文

【Spring 4.0】Spring入門之第一個程式HelloWorld實作

一、關于IOC和DI

    **IOC(Inversion of Control)控制反轉:**其思想是反轉資源擷取的方向. 傳統的資源查找方式要求元件向容器發起請求查找資源. 作為回應, 容器适時的傳回資源. 而應用了 IOC 之後, 則是容器主動地将資源推送給它所管理的元件, 元件所要做的僅是選擇一種合适的方式來接受資源. 這種行為也被稱為查找的被動形式

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

二、Bean的配置

(1)建立一個名為

HelloWorld

的JavaBean

(如果按照上一篇博文過來的朋友則不用做Bean的配置了,隻需看一下解釋就好。因為我是以上一篇的HelloWorld執行個體來講解的)

public class HelloWorld {

	private String user;
	
	public HelloWorld() {
		System.out.println("HelloWorld's constructor...");
	}
	
	public void setUser(String user) {
		System.out.println("setUser:" + user);
		this.user = user;
	}
	
	public HelloWorld(String user) {
		this.user = user;
	}

	public void hello(){
		System.out.println("Hello: " + user);
	}
	
}

           

HelloWorld.Java

(2)在

applicationContext

中為Bean中的屬性指派

<bean id="helloWorld" class="com.spring.helloworld.HelloWorld">
		<!-- 為屬性指派 -->
		<property name="user" value="Jerry"></property>
	</bean>

           

屬性解釋:

屬性 屬性值
class bean 的 指的是HelloWorld的全路徑名稱,并且由于是通過反射方式建立Bean,是以Bean中必須有無參的構造器。如果沒有無參構造器則會出錯,當然如果沒有顯示聲明構造器也無妨,因為虛拟機會隐式建立一個無參的構造器。
id 當建立好一個bean之後,如何引用這個bean呢?就需要使用id.它辨別bean.并且id唯一。id:Bean 的名稱:(1)在 IOC 容器中必須是唯一的。(2)若 id 沒有指定,Spring 自動将權限定性類名作為 Bean 的名字。(3)id 可以指定多個名字,名字之間可用逗号、分号、或空格分隔。

(3)在

Main.java

中通過容器讀出資料

//1. 建立 Spring 的 IOC 容器
		//ApplicationContext:代表IOC容器
		//ClassPathXmlApplicationContext:是ApplicationContext接口的實作類
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
		//2. 從 IOC 容器中擷取 bean 的執行個體
		HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld");
		//根據類型來擷取 bean 的執行個體: 要求在  IOC 容器中隻有一個與之類型比對的 bean, 若有多個則會抛出異常. 
		//一般情況下, 該方法可用, 因為一般情況下, 在一個 IOC 容器中一個類型對應的 bean 也隻有一個. 
//		HelloWorld helloWorld1 = ctx.getBean(HelloWorld.class);
		//3. 使用 bean
		helloWorld.hello();

           

注意!

    在 Spring IOC 容器讀取 Bean 配置建立 Bean 執行個體之前, 必須對它進行執行個體化. 隻有在容器執行個體化後, 才可以從 IOC 容器裡擷取 Bean 執行個體并使用。

三、屬性注入方式

在Spring中,支援三種依賴注入的方式

(1)屬性注入

<!-- 配置一個 bean -->
	<bean id="helloWorld2" class="com.spring.helloworld.HelloWorld">
		<!-- 為屬性指派 -->
		<!-- 通過屬性注入: 通過 setter 方法注入屬性值 -->
		<property name="user" value="Tom"></property>
	</bean>

           
  • 屬性注入即通過 setter 方法注入Bean 的屬性值或依賴的對象
  • 屬性注入使用

    <property>

    元素, 使用

    name

    屬性指定 Bean 的屬性名稱,

    value

    屬性或 子節點指定屬性值
  • 屬性注入是實際應用中最常用的注入方式

(2)構造器注入

示範:

1.添加Car類

public class Car {
	private String company;
	private String brand;
	private int maxSpeed;
	private float price;
	public Car(String company, String brand, float price) {
		super();
		this.company = company;
		this.brand = brand;
		this.price = price;
	}
	public Car(String company, String brand, int maxSpeed) {
		super();
		this.company = company;
		this.brand = brand;
		this.maxSpeed = maxSpeed;
	}
	public Car(String company, String brand, int maxSpeed, float price) {
		super();
		this.company = company;
		this.brand = brand;
		this.maxSpeed = maxSpeed;
		this.price = price;
	}
	@Override
	public String toString() {
		return "Car [company=" + company + ", brand=" + brand + ", maxSpeed="
				+ maxSpeed + ", price=" + price + "]";
	}
}

           

2.配置bean:

<!-- 若一個 bean 有多個構造器, 如何通過構造器來為 bean 的屬性指派? -->
	<!-- 可以根據 index 和 value 進行更加精确的定位. -->
	<bean id="car" class="com.spring.helloworld.Car">
		<constructor-arg value="KUGA" ></constructor-arg>
		<constructor-arg value="ChangAnFord" ></constructor-arg>
		<constructor-arg value="250000" ></constructor-arg>
	</bean>

           

3.主方法調用:

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Car car = (Car) ctx.getBean("car");
System.out.println(car);

           

4.結果

【Spring4.0】 Spring中的Bean配置
注意!

    上面的構造器隻是為了其中的前三個屬性進行初始化,bean中的配置其實是按照順序來初始化的,當然如果構造器非常多,如何對bean進行配置呢?

public Car(String company, String brand, float price) {
		super();
		this.company = company;
		this.brand = brand;
		this.price = price;
	}
	public Car(String company, String brand, int maxSpeed) {
		super();
		this.company = company;
		this.brand = brand;
		this.maxSpeed = maxSpeed;
	}

           

(在Car類中增添兩個構造器)

解決方案:

<bean id="car" class="com.spring.helloworld.Car">
		<constructor-arg value="KUGA" index="1"></constructor-arg>
		<constructor-arg value="ChangAnFord" index="0"></constructor-arg>
		<constructor-arg value="250000" type="float"></constructor-arg>
	</bean>
	<bean id="car3" class="com.spring.helloworld.Car">
		<constructor-arg value="BAOMA" type="java.lang.String"></constructor-arg>
		<constructor-arg value="ChangAnFord" type="java.lang.String"></constructor-arg>
		<constructor-arg value="250000" type="int"></constructor-arg>
	</bean>

           
  • (1)可以建立

    index

    :

    <constructor-arg value="audi" index="0"></constructor-arg>

  • (2)構造函數也是重載的,區分重載的是參數個數和類型,個數不同好辦,相同的時候就可以在後面注明類型。

**(使用`type`來注明類型) ** 結果:

【Spring4.0】 Spring中的Bean配置

四、注入屬性值細節

(1)特殊字元

    字面值:可用字元串表示的值,可以通過

<value>

元素标簽或 value 屬性進行注入。基本資料類型及其封裝類、String 等類型都可以采取字面值注入的方式。若字面值中包含特殊字元,如有尖括号<>等等,可以使用

<![CDATA[]]>

把字面值包裹起來。

<bean id="car2" class="com.spring.helloworld.Car">
		<constructor-arg value="ChangAnMazda"></constructor-arg>
		<!-- 
		字面值也可以通過 <value> 元素标簽
		若字面值中包含特殊字元, 則可以使用 DCDATA 來進行指派. (了解) 
		-->
		<constructor-arg>
			<value><![CDATA[<ATARZA>]]></value>
		</constructor-arg>
		<constructor-arg value="180" type="int"></constructor-arg>
	</bean>

           

(2)引用其他的Bean

    組成應用程式的 Bean 經常需要互相協作以完成應用程式的功能。要使 Bean 能夠互相通路, 就必須在 Bean 配置檔案中指定對 Bean 的引用。在 Bean 的配置檔案中, 可以通過

<ref>

元素或 ref 屬性為 Bean 的屬性或構造器參數指定對 Bean 的引用。也可以在屬性或構造器裡包含 Bean 的聲明, 這樣的 Bean 稱為内部 Bean。

<!-- 配置 bean -->
	<bean id="dao5" class="com.spring.ref.Dao"></bean>
	<bean id="service" class="com.spring.ref.Service">
		<!-- 通過 ref 屬性值指定目前屬性指向哪一個 bean! -->
		<property name="dao" ref="dao5"></property>
	</bean>

           

(3)内部Bean

    當 Bean 執行個體僅僅給一個特定的屬性使用時, 可以将其聲明為内部 Bean. 内部 Bean 聲明直接包含在

<property>

<constructor-arg>

元素裡, 不需要設定任何 id 或 name 屬性。内部 Bean 不能使用在任何其他地方。

<!-- 聲明使用内部 bean -->
	<bean id="service2" class="com.spring.ref.Service">
		<property name="dao">
			<!-- 内部 bean, 類似于匿名内部類對象. 不能被外部的 bean 來引用, 也沒有必要設定 id 屬性 -->
			<bean class="com.spring.ref.Dao">
				<property name="dataSource" value="c3p0"></property>
			</bean>
		</property>
	</bean>

           

(4)Null值

可以使用專用的

<null/>

元素标簽為 Bean 的字元串或其它對象類型的屬性注入 null 值。

<bean id="dao2" class="com.spring.ref.Dao">
		<!-- 為 Dao 的 dataSource 屬性指派為 null, 若某一個 bean
		的屬性值不是 null, 使用時需要為其設定為 null(了解) -->
		<property name="dataSource"><null/></property>
	</bean>

           

(5)級聯屬性

和 Struts、Hiberante 等架構一樣,Spring 支援級聯屬性的配置。

<bean id="action" class="com.spring.ref.Action">
		<property name="service" ref="service2"></property>
		<!-- 設定級聯屬性 -->
		<property name="service.dao.dataSource" value="DBCP2"></property>
</bean>

           

(6)集合屬性

在 Spring中可以通過一組内置的 xml 标簽(例如:

<list>

,

<set>

<map>

) 來配置集合屬性

1.配置

java.util.List

類型的屬性

需要指定

<list>

标簽, 在标簽裡包含一些元素. 這些标簽可以通過

<value>

指定簡單的常量值, 通過

<ref>

指定對其他 Bean 的引用. 通過

<bean>

指定内置 Bean 定義. 通過

<null/>

指定空元素. 甚至可以内嵌其他集合。

<!-- 裝配集合屬性 -->
	<bean id="user" class="com.spring.helloworld.User">
		<property name="userName" value="Jack"></property>
		<property name="cars">
			<!-- 使用 list 元素來裝配集合屬性 -->
			<list>
				<ref bean="car"/>
				<ref bean="car2"/>
			</list>
		</property>
	</bean>

           

注意!

數組的定義和 List 一樣, 都使用

<list>

2.配置

java.util.Set

類型的屬性

java.util.Map

通過

<map>

标簽定義,

<map>

标簽裡可以使用多個

<entry>

作為子标簽. 每個條目包含一個鍵和一個值。

<bean id="user7" class="com.spring.helloworld.User">
		<property name="userName" value="Rose"></property>
		<property name="wifeName" value="JACK"></property>
		<!-- 使用 Map 元素來裝配集合屬性  -->
		<property name="carmap">
			<map>
				<entry key="AA" value-ref="car"></entry>
				<entry key="BB" value-ref="car"></entry>
			</map>
		</property>
	</bean>

           

注意!

  • 必須在

    <key>

    标簽裡定義鍵
  • 因為鍵和值的類型沒有限制, 是以可以自由地為它們指定

    <value>

    ,

    <ref>

    ,

    <bean>

    <null>

    元素。
  • 可以将 Map 的鍵和值作為

    <entry>

    的屬性定義: 簡單常量使用

    key

    value

    來定義; Bean 引用通過

    key-ref

    value-ref

    屬性定義。
3.配置

java.util.Properties

類型的屬性

    使用

<props>

定義

java.util.Properties

, 該标簽使用多個

<prop>

作為子标簽. 每個

<prop>

标簽必須定義

key

屬性.實際應用于配置資料庫連接配接池。

第一步:建立DataSource類

import java.util.Properties;

public class DataSource {
	private Properties properties;
	public Properties getProperties() {
		return properties;
	}
	public void setProperties(Properties properties) {
		this.properties = properties;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "DataSoure [properties=" + properties +"]" ;
	}
}

           

第二步:配置bean

<bean id="dataSource" class="com.spring.helloworld.DataSource">
		<property name="properties" >
			<props>
				<prop key="user">rout</prop>
				<prop key="password">rout</prop>
				<prop key="jdbcUrl">jdbc:mysql://localhost/hibernate</prop>
				<prop key="driverClass">com.mysql.jdbc.Driver</prop>
			</props>
		</property>
	</bean>

           

第三步:列印相關資訊

DataSource dataSource = (DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);

           

第四步:結果

DataSoure[properties={driverClass=com.mysql.jdbc.Driver, user=rout, password=rout, jdbcUrl=jdbc:mysql://localhost/hibernate}]
           
4.使用

utility scheme

定義集合

    使用基本的集合标簽定義集合時, 不能将集合作為獨立的 Bean 定義, 導緻其他 Bean 無法引用該集合, 是以無法在不同 Bean 之間共享集合.。可以使用 util schema 裡的集合标簽定義獨立的集合 Bean. 需要注意的是, 必須在

<beans>

根元素裡添加 util schema 定義。

第一步:導入util命名空間

打開

applicationContext

如圖按順序設定

【Spring4.0】 Spring中的Bean配置

第二步:使用

util:list

聲明集合類型的 bean

<!-- 聲明集合類型的 bean -->
	<util:list id="cars">
		<ref bean="car"/>
		<ref bean="car2"/>
	</util:list>
	<bean id="user2" class="com.spring.helloworld.User">
		<property name="userName" value="Rose"></property>
		<!-- 引用外部聲明的 list -->
		<property name="cars" ref="cars"></property>
	</bean>

           
5.使用 p 命名空間

為了簡化 XML 檔案的配置,越來越多的 XML 檔案采用屬性而非子元素配置資訊。Spring 從 2.5 版本開始引入了一個新的 p 命名空間,可以通過

<bean>

元素屬性的方式配置 Bean 的屬性。使用 p 命名空間後,基于 XML 的配置方式将進一步簡化。

<!-- 通過p命名空間為bean的屬性指派,需要導入p命名空間 -->
	<bean id="user3" class="com.spring.helloworld.User"
		p:cars-ref="cars" p:userName="Titannic"></bean>

           

繼續閱讀