Spring3系列5-Bean的基本用法
本篇講述了Bean的基本配置方法,以及Spring中怎樣運用Bean。
主要內容如下:
一、 Spring中Bean的相互引用
二、 Spring中給Bean屬性注入value
三、 Spring Inner Bean—內部嵌套的Bean
四、 Spring Bean Scopes—Bean的作用域
五、 Spring Collections(List、Set、Map、Properties) — 集合類型的Bean
一、 Spring中Bean的相互引用
在Spring框架中,可以通過ref來互相引用相同或不同xml配置文件中定義的Bean。
1. 引用不同xml配置文件中的bean
如果你想引用不同xml配置文件中的bean,可以使用’ref’標簽,結合’bean’屬性。
格式:<ref bean="someBean"/>
在下邊的例子中,bean’ OutputHelper’在’ Spring-Common.xml’文件中被定義,通過使用’ref’標簽,結合’bean’屬性,可以引用’ Spring-Output.xml’文件中定義的兩個bean(“CsvOutputGenerator” 和 “JsonOutputGenerator“)
配置文件:Spring-Output.xml如下
<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-2.5.xsd"> <bean id="CsvOutputGenerator" class="com.lei.output.impl.CsvOutputGenerator" /> <bean id="JsonOutputGenerator" class="com.lei.output.impl.JsonOutputGenerator" /> </beans>
配置文件: Spring-Common.xml如下
<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-2.5.xsd"> <bean id="OutputHelper" class="com.lei.output.OutputHelper"> <property name="outputGenerator" > <ref bean="CsvOutputGenerator"/> </property> </bean> </beans>
2. 引用相同xml配置文件中的bean
如果你想引用相同xml配置文件中的bean,可以使用’ref’標簽,結合’local’屬性。
格式:<ref local="someBean"/>
配置文件:Spring-Output.xml如下
<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-2.5.xsd"> <bean id="OutputHelper" class="com.lei.output.OutputHelper"> <property name="outputGenerator" > <ref local="CsvOutputGenerator"/> </property> </bean> <bean id="CsvOutputGenerator" class="com.lei.output.impl.CsvOutputGenerator" /> <bean id="JsonOutputGenerator" class="com.lei.output.impl.JsonOutputGenerator" /> </beans>
注意
實際上,’ref’標簽中’bean’屬性,既可以引用相同xml文件中的bean,也可以引用不同xml文件中的bean,但是,考慮到項目的可讀性,引用相同xml配置文件的bean時,應該盡量使用’local’屬性。
二、 Spring中給Bean屬性注入value
Spring中,通常有3種方法給Bean的屬性注入value。
一般方法,縮寫方法,”p” schema方法。
先看下邊的Bean:FileNameGenerator.java,其中包含兩個properties,name和type,我們向兩個properties注入value。
package com.lei.common; public class FileNameGenerator { private String name; private String type; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } }
1. 一般方法
<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-2.5.xsd"> <bean id="FileNameGenerator" class="com.lei.common.FileNameGenerator"> <property name="name"> <value>lei</value> </property> <property name="type"> <value>txt</value> </property> </bean> </beans>
2. 縮寫方法
<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-2.5.xsd"> <bean id="FileNameGenerator" class="com.lei.common.FileNameGenerator"> <property name="name" value="lei" /> <property name="type" value="txt" /> </bean> </beans>
3. ”p” schema
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="FileNameGenerator" class="com.lei.common.FileNameGenerator" p:name="lei" p:type="txt" /> </beans>
注意,這種方法需要在bean的配置文件xml中,加入以下聲明
xmlns:p=”http://www.springframework.org/schema/p
三、 Spring Inner Bean—內部嵌套的Bean
以下Demo演示了一個Bean中嵌套了另一個Bean,即所謂的內部嵌套Bean的配置方法,內部嵌套的Bean支持屬性(property)注入和構造函數(constructor-arg)注入。
先看一下Customer.java 和Person.java
package com.lei.common; public class Customer { private Person person; public Customer(Person person) { this.person = person; } public void setPerson(Person person) { this.person = person; } @Override public String toString() { return "Customer [person=" + person + "]"; } }
package com.lei.common; public class Person { private String name; private String address; private int age; //getter and setter methods…此處省略 @Override public String toString() { return "Person [address=" + address + ", age=" + age + ", name=" + name + "]"; } }
配置Bean時,要在Customer的Bean中注入內部Bean,即Person。
1. 在Customer中,可以用’ref’屬性引用Person的Bean,如下
<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-2.5.xsd"> <bean id="CustomerBean" class="com.lei.common.Customer"> <property name="person" ref="PersonBean" /> </bean> <bean id="PersonBean" class="com.lei.common.Person"> <property name="name" value="lei" /> <property name="address" value="address1" /> <property name="age" value="28" /> </bean> </beans>
2. 以上方法利用’ref’很好的引用了Person,但是,一旦Person僅僅被用在Customer下,也就是說不會被別的Bean引用,最好的方法就是在Customer的bean中聲明一個內部Bean,如下
<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-2.5.xsd"> <bean id="CustomerBean" class="com.lei.common.Customer"> <property name="person"> <bean class="com.lei.common.Person"> <property name="name" value="lei" /> <property name="address" value="address1" /> <property name="age" value="28" /> </bean> </property> </bean> </beans>
3. 內部Bean也可以通過構造函數注入
<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-2.5.xsd"> <bean id="CustomerBean" class="com.lei.common.Customer"> <constructor-arg> <bean class="com.lei.common.Person"> <property name="name" value="lei" /> <property name="address" value="address1" /> <property name="age" value="28" /> </bean> </constructor-arg> </bean> </beans>
注意,以上2,3兩種情況下,Person的Bean配置中,可以忽略id屬性。
四、 Spring Bean Scopes—Bean的作用域
在Spring中,Bean的作用域決定了從Spring容器中返回的Bean實例的類型。
在Spring中,支持以下5中類型的作用域:
- singleton — 單例模式,由IOC容器返回一個唯一的bean實例。
- prototype — 原型模式,被請求時,每次返回一個新的bean實例。
- request — 每個HTTP Request請求返回一個唯一的Bean實例。
- session — 每個HTTP Session返回一個唯一的Bean實例。
- globalSession — Http Session全局Bean實例。
注:大多數情況下,你可能只需要處理Spring的核心作用域 — 單例模式(singleton)和原型模式(prototype),默認情況下,作用域是單例模式。
singleton和prototype區別
CustomerService.java如下
package com.lei.customer.services; public class CustomerService { String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
如果是singleton情況下的配置如下
<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-2.5.xsd"> <bean id="customerService" class="com.lei.customer.services.CustomerService" /> </beans>
以上配置中,如果沒有指定scope范圍,默認情況下是sighleton模式。
運行下邊的代碼:
package com.lei.common; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.lei.customer.services.CustomerService; public class App { public static void main( String[] args ) { ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"Spring-Customer.xml"}); CustomerService custA = (CustomerService)context.getBean("customerService"); custA.setMessage("Message by custA"); System.out.println("Message : " + custA.getMessage()); //retrieve it again CustomerService custB = (CustomerService)context.getBean("customerService"); System.out.println("Message : " + custB.getMessage()); } }
輸出結果如下:
Message : Message by custA
Message : Message by custA
Protptype情況下的配置如下:
<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-2.5.xsd"> <bean id="customerService" class="com.lei.customer.services.CustomerService" scope="prototype"/> </beans>
再運行一下測試代碼,輸出結果如下:
Message : Message by custA
Message : null
設置scope為prototype后,測試代碼中,每調用一次getBean()方法后,都會得到一個新的實例。
五、 Spring Collections(List、Set、Map、Properties) — 集合類型的Bean
本節講述怎樣將值注入集合類型,包含以下四種主要的集合類型:
List —— <list/>
Set —— <set/>
Map —— <map/>
Properties —— <props/>
首先寫一個Bean,一個Customer對象,包含四種集合屬性,如下,
Customer.java
package com.lei.common; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; public class Customer { private List<Object> lists; private Set<Object> sets; private Map<Object, Object> maps; private Properties pros; //...此處省略setter和getter }
1. List
<property name="lists"> <list> <value>1</value> <ref bean="PersonBean" /> <bean class="com.lei.common.Person"> <property name="name" value="leiList" /> <property name="address" value="address" /> <property name="age" value="28" /> </bean> </list> </property>
2. Set
<property name="sets"> <set> <value>1</value> <ref bean="PersonBean" /> <bean class="com.lei.common.Person"> <property name="name" value="leiSet" /> <property name="address" value="address" /> <property name="age" value="28" /> </bean> </set> </property>
3. Map
<property name="maps"> <map> <entry key="Key 1" value="1" /> <entry key="Key 2" value-ref="PersonBean" /> <entry key="Key 3"> <bean class="com.lei.common.Person"> <property name="name" value="leiMap" /> <property name="address" value="address" /> <property name="age" value="28" /> </bean> </entry> </map> </property>
4. Properties
<property name="pros"> <props> <prop key="admin">admin@nospam.com</prop> <prop key="support">support@nospam.com</prop> </props> </property>
綜上,所有的bean配置文件如下
<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-2.5.xsd"> <bean id="CustomerBean" class="com.lei.common.Customer"> <!-- java.util.List --> <property name="lists"> <list> <value>1</value> <ref bean="PersonBean" /> <bean class="com.lei.common.Person"> <property name="name" value="leiList" /> <property name="address" value="address" /> <property name="age" value="28" /> </bean> </list> </property> <!-- java.util.Set --> <property name="sets"> <set> <value>1</value> <ref bean="PersonBean" /> <bean class="com.lei.common.Person"> <property name="name" value="leiSet" /> <property name="address" value="address" /> <property name="age" value="28" /> </bean> </set> </property> <!-- java.util.Map --> <property name="maps"> <map> <entry key="Key 1" value="1" /> <entry key="Key 2" value-ref="PersonBean" /> <entry key="Key 3"> <bean class="com.lei.common.Person"> <property name="name" value="leiMap" /> <property name="address" value="address" /> <property name="age" value="28" /> </bean> </entry> </map> </property> <!-- java.util.Properties --> <property name="pros"> <props> <prop key="admin">admin@nospam.com</prop> <prop key="support">support@nospam.com</prop> </props> </property> </bean> <bean id="PersonBean" class="com.lei.common.Person"> <property name="name" value="lei1" /> <property name="address" value="address 1" /> <property name="age" value="28" /> </bean> </beans>
