国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > Java > 正文

Spring工廠方法創(chuàng)建(實(shí)例化)bean實(shí)例代碼

2024-07-13 10:16:17
字體:
供稿:網(wǎng)友

目標(biāo)明確

簡(jiǎn)單敘述一下本文想要解決的問題:如何在Spring中不再使用Spring創(chuàng)建Bean實(shí)例,而是把Bean創(chuàng)建過程轉(zhuǎn)移到開發(fā)者手中。

思路清晰

創(chuàng)建Bean實(shí)例的方式:

1) 通過構(gòu)造器(有參或無參)

方式: <bean id="" class=""/>

2) 通過靜態(tài)工廠方法

方式: <bean id="" class="工廠類" factory-method="靜態(tài)工廠方法"/>

注: 工廠類實(shí)例沒有創(chuàng)建

3) 通過實(shí)例工廠方法(非靜態(tài)方法)

方式:

<bean id="factory" class="工廠類"/>

<bean id="" factory-bean="factory" factory-method="實(shí)例工廠方法"/>

注: 工廠類實(shí)例被創(chuàng)建

方法實(shí)用

示例1

需求:

1 不想再bean.xml加載的時(shí)候?qū)嵗痓ean,而是想把加載bean.xml與實(shí)例化對(duì)象分離。

2 實(shí)現(xiàn)單例的bean

以上的情況,都可以通過工廠方法factory-method來創(chuàng)建bean。

這樣再加載bean.xml時(shí),不會(huì)直接實(shí)例化bean,而是當(dāng)調(diào)用factory-method所指的方法時(shí),才開始真正的實(shí)例化。

實(shí)現(xiàn):通過spring的factory-method來創(chuàng)建單例的bean
  首先通過靜態(tài)內(nèi)部類創(chuàng)建一個(gè)單例對(duì)象

package com.spring.test.factorymethod;public class Stage {  public void perform(){    System.out.println("演出開始...");  }  private Stage(){      }  private static class StageSingletonHolder{    static Stage instance = new Stage();  }  public static Stage getInstance(){    return StageSingletonHolder.instance;  }}

在spring配置文件中指定加載的方法getInstance

<?xml version="1.0" encoding="UTF-8"?><beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns="http://www.springframework.org/schema/beans"  xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">   <bean id="theStage" class="com.spring.test.factorymethod.Stage"     factory-method="getInstance"></bean></beans>

通過應(yīng)用上下文調(diào)用bean獲取實(shí)例

package com.spring.test.factorymethod;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class test {  public static void main(String[] args) {    ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");    Stage stage = ((Stage)ctx.getBean("theStage"));//.getInstance();    stage.perform();  }}

執(zhí)行結(jié)果

一月 24, 2015 6:38:18 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@512dbd1a: startup date [Sat Jan 24 18:38:18 CST 2015]; root of context hierarchy一月 24, 2015 6:38:19 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions信息: Loading XML bean definitions from class path resource [bean.xml]一月 24, 2015 6:38:19 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2d1879ea: defining beans [duke,sonnet29,poeticDuke,theStage]; root of factory hierarchy演出開始...

工廠方法創(chuàng)建bean介紹

1. 使用靜態(tài)工廠方法創(chuàng)建Bean

使用靜態(tài)工廠方法創(chuàng)建Bean實(shí)例時(shí),class屬性也必須指定,但此時(shí)class屬性并不是指定Bean實(shí)例的實(shí)現(xiàn)類,而是靜態(tài)工廠類。因?yàn)镾pring需要知道是用哪個(gè)工廠來創(chuàng)建Bean實(shí)例。另外,還需要使用factory-method來指定靜態(tài)工廠方法名,Spring將調(diào)用靜態(tài)工廠方法(可能包含一組參數(shù)),來返回一個(gè)Bean實(shí)例,一旦獲得了指定Bean實(shí)例,Spring后面的處理步驟與采用普通方法創(chuàng)建Bean實(shí)例則完全一樣。需要注意的是,當(dāng)使用靜態(tài)工廠方法來創(chuàng)建Bean時(shí),這個(gè)factory-method必須要是靜態(tài)的。這段闡述聽上去有點(diǎn)暈,話不多說,上代碼:

先定義一個(gè)接口,靜態(tài)方法產(chǎn)生的將是該接口的實(shí)例:

public interface Animal {  public void sayHello();}

下面是接口的兩個(gè)實(shí)現(xiàn)類:

public class Cat implements Animal {  private String msg;  //依賴注入時(shí)必須的setter方法  public void setMsg(String msg){    this.msg = msg;  }  @Override  public void sayHello(){    System.out.println(msg + ",喵~喵~");  }} public class Dog implements Animal {  private String msg;  //依賴注入時(shí)必須的setter方法  public void setMsg(String msg){    this.msg = msg;  }  @Override  public void sayHello(){    System.out.println(msg + ",旺~旺~");  }}

下面的AnimalFactory工廠中包含了一個(gè)getAnimal的靜態(tài)方法,該方法將根據(jù)傳入的參數(shù)決定創(chuàng)建哪個(gè)對(duì)象。這是典型的靜態(tài)工廠設(shè)計(jì)模式。

public clas AnimalFactory {  public static Animal getAnimal(String type){    if ("cat".equalsIgnoreCase(type)){      return new Cat();    } else {      return new Dog();    }  }}

如果需要指定Spring使用AnimalFactory來產(chǎn)生Animal對(duì)象,則可在Spring配置文件中作如下配置:

<!-- 配置AnimalFactory的getAnimal方法,使之產(chǎn)生Cat --><bean id="cat" class="com.abc.AnimalFactory" factory-method="getAnimal">  <!-- 配置靜態(tài)工廠方法的參數(shù),getAnimal方法將產(chǎn)生Cat類型的對(duì)象 -->  <constructor-arg value="cat" />  <!-- 通過setter注入的普通屬性 -->  <property name="msg" value="貓貓" /></bean><!-- 配置AnimalFactory的getAnimal方法,使之產(chǎn)生Dog --><bean id="dog" class="com.abc.AnimalFactory" factory-method="getAnimal">  <!-- 配置靜態(tài)工廠方法的參數(shù),getAnimal方法將產(chǎn)生Dog類型的對(duì)象 -->  <constructor-arg value="dog" />  <!-- 通過setter注入的普通屬性 -->  <property name="msg" value="狗狗" /></bean>

從上面的配置可以看出:cat和dog兩個(gè)Bean配置的class和factory-method完全相同,這是因?yàn)閮蓚€(gè)實(shí)例都使用同一個(gè)靜態(tài)工廠類、同一個(gè)靜態(tài)工廠方法產(chǎn)生得到的。只是為這個(gè)靜態(tài)工廠方法指定的參數(shù)不同,使用<constructor-arg />元素來為靜態(tài)工廠方法指定參數(shù)。

主程序獲取cat和dog兩個(gè)Bean實(shí)例的方法不變,同樣只需要調(diào)用Spring容器的getBean()即可:

public class Test {  public static void main(String args[]){    ApplicationContext context =         new ClassPathXmlApplicationContext("applicationContext.xml");    Animal a1 = context.getBean("cat", Animal.class);    a1.sayHello();    Animal a2 = context.getBean("dog", Animal.class);    a2.sayHello();  }}

輸出結(jié)果:

<code class="hljs">貓貓,喵~喵~狗狗,旺~旺~</code>

使用靜態(tài)工廠方法創(chuàng)建實(shí)例時(shí)必須提供工廠類和產(chǎn)生實(shí)例的靜態(tài)工廠方法。通過靜態(tài)工廠方法創(chuàng)建實(shí)例時(shí)需要對(duì)Spring配置文件做如下改變;

class屬性不在是Bean實(shí)例的實(shí)現(xiàn)類,而是生成Bean實(shí)例的靜態(tài)工廠類

使用factory-method指定生產(chǎn)Bean實(shí)例的靜態(tài)工廠方法

如果靜態(tài)工廠方法需要參數(shù),使用<constructor-arg />元素為其配置

當(dāng)我們指定Spring使用靜態(tài)工廠方法來創(chuàng)建Bean實(shí)例時(shí),Spring將先解析配置文件,并根據(jù)配置文件指定的信息,通過反射調(diào)用靜態(tài)工廠類的靜態(tài)工廠方法,并將該靜態(tài)工廠方法的返回值作為Bean實(shí)例,在這個(gè)過程中,Spring不再負(fù)責(zé)創(chuàng)建Bean實(shí)例,Bean實(shí)例是由用戶提供的靜態(tài)工廠方法提供的。

2. 使用實(shí)例工廠方法創(chuàng)建Bean

實(shí)例工廠方法與靜態(tài)工廠方法只有一點(diǎn)不同:調(diào)用靜態(tài)工廠方法只需要使用工廠類即可,調(diào)用實(shí)例工廠方法則必須使用工廠實(shí)例。所以在Spring配置上也只有一點(diǎn)區(qū)別:配置靜態(tài)工廠方法指定靜態(tài)工廠類,配置實(shí)例工廠方法則指定工廠實(shí)例。同樣是上面的例子將AnimalFactory修改為:

public clas AnimalFactory {  public Animal getAnimal(String type){ //這里僅僅是去掉了static關(guān)鍵字    if ("cat".equalsIgnoreCase(type)){      return new Cat();    } else {      return new Dog();    }  }}

Spring文件修改為:

<!-- 先配置工廠類 --><bean id="animalFactory" class="com.abc.AnimalFactory" /><!-- 這里使用factory-bean指定實(shí)例工廠類對(duì)象 --><bean id="cat" factory-bean="animalFactory" factory-method="getAnimal">  <!-- 同樣指定factory-method的參數(shù) -->  <constructor-arg value="cat" />  <property name="msg" value="貓貓" /></bean><bean id="dog" factory-bean="animalFactory" factory-method="getAnimal">  <constructor-arg value="dog" />  <property name="msg" value="狗狗" /></bean>

測(cè)試類不用修改,輸出結(jié)果和上面相同。

很多情況下使用<bean id=”bean1” class=”…” />定義一個(gè)bean,這種定義方式Spring將會(huì)調(diào)用默認(rèn)的無參數(shù)構(gòu)造方法創(chuàng)建Bean實(shí)例。除此之外還可以使用工廠方式創(chuàng)建Bean實(shí)例,實(shí)現(xiàn)Bean創(chuàng)建與使用的分離,將Bean創(chuàng)建工作交由工廠來完成。

配置工廠Bean的三種方式。

抽象接口:

public interface IMusicBox {    public void play(); } 

1、靜態(tài)工廠方法取得Bean實(shí)例

工廠類:

public class MusicBoxFactory {   public static IMusicBox createMusicBox(){   return new IMusicBox(){        public void play(){     System.out.println("Play piano...");      }   };   } } 

配置文件:

<bean id="musicBox" class="test.spring.MusicBoxFactory" factory-method="createMusicBox" /> 

測(cè)試類:

public static void main(String[] args) {   ApplicationContext ctx =    new ClassPathXmlApplicationContext("bean-config.xml");   IMusicBox musicbox = (IMusicBox)ctx.getBean("musicBox");   musicbox.play(); } 

2、工廠實(shí)例的方法取得Bean實(shí)例

工廠類:

public class MusicBoxFactory {   public IMusicBox createMusicBox(){//沒有static修飾   return new IMusicBox(){        public void play(){     System.out.println("Play piano...");      }   };   } } 

配置文件:

<bean id="factoryBean" class="test.spring.MusicBoxFactory" /> <bean id="musicBox" factory-bean="factoryBean" factory-method="createMusicBox" /> 

“factory-bean”屬性指定工廠Bean,”factory-method”屬性指定工廠方法來取得Bean實(shí)例。

測(cè)試類:

public static void main(String[] args) {   ApplicationContext ctx =    new ClassPathXmlApplicationContext("bean-config.xml");   IMusicBox musicbox = (IMusicBox)ctx.getBean("musicBox");   musicbox.play(); } 

3、工廠類實(shí)現(xiàn)org.springframework.beans.factory.FacotryBean接口

工廠類:

import org.springframework.beans.factory.FactoryBean;  public class MusicBoxFactory2 implements FactoryBean {   public Object getObject() throws Exception {   return new IMusicBox(){     public void play(){        System.out.println("Play piano...");        }   };   }    public Class getObjectType() {   return IMusicBox.class;   }    public boolean isSingleton() {   return false;   } } 

配置文件:

<bean id="musicBox" class="test.spring.MusicBoxFactory2"/> 

測(cè)試類:

public static void main(String[] args) {   ApplicationContext ctx =    new ClassPathXmlApplicationContext("bean-config.xml");   //不加 & 返回工廠的“產(chǎn)品”   IMusicBox musicbox = (IMusicBox)ctx.getBean("musicBox");   musicbox.play();   //加 & 返回工廠類實(shí)例   Object obj = ctx.getBean("&musicBox");    System.out.println(obj.getClass().getName());   } 

實(shí)現(xiàn)FactoryBean接口的類不會(huì)被視為普通的Bean,Spring會(huì)自動(dòng)檢測(cè),調(diào)用getObject方法獲取Bean實(shí)例

總結(jié)

Spring工廠方法實(shí)例化bean實(shí)例的介紹就到這里,有什么不足之處,大家可以留言指出。感謝朋友們對(duì)本站的支持!


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到JAVA教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 塔河县| 德江县| 肇源县| 岳阳市| 广南县| 永德县| 荥阳市| 海宁市| 荃湾区| 聂拉木县| 阜城县| 安岳县| 峨山| 内丘县| 台州市| 抚松县| 乌审旗| 邯郸市| 长白| 旅游| 营山县| 商丘市| 泗洪县| 姚安县| 稷山县| 宣汉县| 曲阳县| 日土县| 鄄城县| 凤翔县| 图木舒克市| 伊宁市| 土默特左旗| 长顺县| 昭苏县| 太康县| 贡觉县| 广灵县| 张家港市| 平昌县| 工布江达县|