Spring三 Bean的三種創建方式


創建Bean的三種方式
在大多數情況下,Spring容器直接通過new關鍵字調用構造器來創建Bean實例,而class屬性指定Bean實例的實現類,但這不是實例化Bean的唯一方法。實際上,Spring支持使用以下三種方式來創建Bean:
(1)調用構造器創建Bean
(2)調用靜態工廠方法創建Bean
(3)調用實例工廠方法創建Bean
一 構造器創建Bean實例
如果不采用構造注入,Spring底層會調用Bean類的無參數構造器來創建實例,因此該類必須要提供無參數的構造器,並且class屬性的值就是該Bean實例的實現類。Spring對Bean實例的所有屬性執行默認初始化,即所有基本類型的值初始化為0或false,所有引用類型的值初始化為null。BeanFactory會根據配置文件決定依賴關系,先實例化所依賴的Bean實例,然后為Bean注入依賴關系,最后將一個完整的Bean實例返回給程序。
如果采用構造注入,則使用<constructor-arg>配置一個構造器參數,Spring容器將使用帶對應參數的構造器來創建Bean實例,Spring調用構造器傳入的參數即可用於初始化Bean的實例變量,最后也將一個完整的Bean實例返回給程序。
二 使用靜態工廠方法創建Bean
采用靜態工廠方法創建Bean實例時,<bean>元素需要指定兩個屬性:
class:值為靜態工廠類的類名
factory-method:指定靜態工廠方法來生產Bean實例
如果靜態工廠方法需要參數,則使用<constructor-arg>元素傳入。
Being.java
public interface Being {
public void testBeing();
}
Dog.java
public class Dog implements Being {
public void setMsg(String msg) {
this.msg = msg;
}
private String msg;
@Override
public void testBeing() {
System.out.println(msg+",狗愛啃骨頭");
}
}
Cat.java
public class Cat implements Being {
public void setMsg(String msg) {
this.msg = msg;
}
private String msg;
@Override
public void testBeing() {
System.out.println(msg+",貓喜歡吃老鼠");
}
}
BeingFactory.java
BeingFactory工廠包含了一個getBeing()靜態方法,該靜態方法用於返回Being實例。
public class BeingFactory {
public static Being getBeing(String arg){
if(arg.equalsIgnoreCase("dog")){
return new Dog();
}else{
return new Cat();
}
}
}
BeingFactory類是一個靜態工廠類,該類的getBeing()方法是一個靜態工廠方法,該方法傳入的參數決定返回Cat對象,還是Dog對象。
public class BeingFactory {
public static Being getBeing(String msg){
if(msg.equalsIgnoreCase("dog")){
return new Dog();
}else{
return new Cat();
}
}
}
ApplicationContext.xml
//以下配置會驅動Spring調用BeingFactory的靜態getBeing()方法來創建Bean,該Bean元素包含的constructor-arg元素用於為靜態工廠方法指定參數
<bean id="dog" class="SpringTest.BeingFactory" factory-method="getBeing">
<constructor-arg value="dog" />
//驅動Spring以"狗呢"為參數來執行dog的setMsg()方法
<property name="msg" value="狗呢" />
</bean>

<bean id="cat" class="SpringTest.BeingFactory" factory-method="getBeing">
<constructor-arg value="cat" />
<property name="msg" value="貓呢" />
</bean>
測試:
public class MainTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("SpringTest/ApplicationContext.xml");
Being b1=ctx.getBean("dog",Being.class);
b1.testBeing();
Being b2=ctx.getBean("cat",Being.class);
b2.testBeing();
ctx.close();
}
}
結果:狗呢,狗愛啃骨頭
貓呢,貓喜歡吃老鼠
一旦為<bean>元素指定了factory-method屬性,Spring就不再調用構造器來創建Bean實例,而是調用工廠方法來創建Bean實例。如果同時指定了class和factory-method兩個屬性,Spring就會調用靜態工廠方法來創建Bean。
Spring將先解析配置文件,並根據配置文件指定的信息,通過反射調用靜態工廠類的靜態工廠方法,將該靜態工廠方法的返回值作為Bean實例。在這個過程中,Spring不再負責創建Bean實例,Bean實例是由用戶提供的靜態工廠類負責創建的。
三 調用實例工廠方法創建Bean
實例工廠方法與靜態工廠方法只有一點不同:調用靜態工廠方法只需要使用工廠類即可,而調用實例工廠方法則需要工廠實例。所以在配置時,靜態工廠方法使用class指定靜態工廠類,實例工廠方法使用factory-bean指定工廠實例。
采用實例工廠方法創建Bean的<bean>元素時需要指定兩個屬性:
factory-bean:工廠bean的id
factory-method:實例工廠的工廠方法
修改BeanFactory.java和AppliactionContext.xml
BeanFactory.java
public class BeingFactory {
public Being getBeing(String msg){
if(msg.equalsIgnoreCase("dog")){
return new Dog();
}else{
return new Cat();
}
}
}
ApplicationContext.xml
<bean id="beingFactory" class="SpringTest.BeingFactory" />
<bean id="dog" factory-bean="beingFactory" factory-method="getBeing">
<constructor-arg value="dog" />
</bean>

<bean id="cat" factory-bean="beingFactory" factory-method="getBeing">
<constructor-arg value="cat" />
</bean>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM