亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

Spring工廠方法創建(實例化)bean實例代碼

2024-07-13 10:16:17
字體:
來源:轉載
供稿:網友

目標明確

簡單敘述一下本文想要解決的問題:如何在Spring中不再使用Spring創建Bean實例,而是把Bean創建過程轉移到開發者手中。

思路清晰

創建Bean實例的方式:

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

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

2) 通過靜態工廠方法

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

注: 工廠類實例沒有創建

3) 通過實例工廠方法(非靜態方法)

方式:

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

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

注: 工廠類實例被創建

方法實用

示例1

需求:

1 不想再bean.xml加載的時候實例化bean,而是想把加載bean.xml與實例化對象分離。

2 實現單例的bean

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

這樣再加載bean.xml時,不會直接實例化bean,而是當調用factory-method所指的方法時,才開始真正的實例化。

實現:通過spring的factory-method來創建單例的bean
  首先通過靜態內部類創建一個單例對象

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>

通過應用上下文調用bean獲取實例

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();  }}

執行結果

一月 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演出開始...

工廠方法創建bean介紹

1. 使用靜態工廠方法創建Bean

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

先定義一個接口,靜態方法產生的將是該接口的實例:

public interface Animal {  public void sayHello();}

下面是接口的兩個實現類:

public class Cat implements Animal {  private String msg;  //依賴注入時必須的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;  //依賴注入時必須的setter方法  public void setMsg(String msg){    this.msg = msg;  }  @Override  public void sayHello(){    System.out.println(msg + ",旺~旺~");  }}

下面的AnimalFactory工廠中包含了一個getAnimal的靜態方法,該方法將根據傳入的參數決定創建哪個對象。這是典型的靜態工廠設計模式。

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

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

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

從上面的配置可以看出:cat和dog兩個Bean配置的class和factory-method完全相同,這是因為兩個實例都使用同一個靜態工廠類、同一個靜態工廠方法產生得到的。只是為這個靜態工廠方法指定的參數不同,使用<constructor-arg />元素來為靜態工廠方法指定參數。

主程序獲取cat和dog兩個Bean實例的方法不變,同樣只需要調用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();  }}

輸出結果:

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

使用靜態工廠方法創建實例時必須提供工廠類和產生實例的靜態工廠方法。通過靜態工廠方法創建實例時需要對Spring配置文件做如下改變;

class屬性不在是Bean實例的實現類,而是生成Bean實例的靜態工廠類

使用factory-method指定生產Bean實例的靜態工廠方法

如果靜態工廠方法需要參數,使用<constructor-arg />元素為其配置

當我們指定Spring使用靜態工廠方法來創建Bean實例時,Spring將先解析配置文件,并根據配置文件指定的信息,通過反射調用靜態工廠類的靜態工廠方法,并將該靜態工廠方法的返回值作為Bean實例,在這個過程中,Spring不再負責創建Bean實例,Bean實例是由用戶提供的靜態工廠方法提供的。

2. 使用實例工廠方法創建Bean

實例工廠方法與靜態工廠方法只有一點不同:調用靜態工廠方法只需要使用工廠類即可,調用實例工廠方法則必須使用工廠實例。所以在Spring配置上也只有一點區別:配置靜態工廠方法指定靜態工廠類,配置實例工廠方法則指定工廠實例。同樣是上面的例子將AnimalFactory修改為:

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

Spring文件修改為:

<!-- 先配置工廠類 --><bean id="animalFactory" class="com.abc.AnimalFactory" /><!-- 這里使用factory-bean指定實例工廠類對象 --><bean id="cat" factory-bean="animalFactory" factory-method="getAnimal">  <!-- 同樣指定factory-method的參數 -->  <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>

測試類不用修改,輸出結果和上面相同。

很多情況下使用<bean id=”bean1” class=”…” />定義一個bean,這種定義方式Spring將會調用默認的無參數構造方法創建Bean實例。除此之外還可以使用工廠方式創建Bean實例,實現Bean創建與使用的分離,將Bean創建工作交由工廠來完成。

配置工廠Bean的三種方式。

抽象接口:

public interface IMusicBox {    public void play(); } 

1、靜態工廠方法取得Bean實例

工廠類:

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" /> 

測試類:

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

2、工廠實例的方法取得Bean實例

工廠類:

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實例。

測試類:

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

3、工廠類實現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"/> 

測試類:

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

實現FactoryBean接口的類不會被視為普通的Bean,Spring會自動檢測,調用getObject方法獲取Bean實例

總結

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


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品女厕一区二区三区| 国产精品91久久| 久久久精品亚洲| www.日韩不卡电影av| 久久久国产在线视频| 欧美中文字幕在线| 欧美一级片在线播放| 日韩av手机在线| 亚洲精品美女视频| 国产成人久久久精品一区| 国产一区二区三区视频免费| 亚洲娇小xxxx欧美娇小| 国产一区二区动漫| 国产精品欧美日韩| 日韩专区在线观看| 亚洲色图在线观看| 国产精品va在线播放| 668精品在线视频| 久久精品国产96久久久香蕉| 欧美老肥婆性猛交视频| 成人观看高清在线观看免费| 国产激情视频一区| 国产精品96久久久久久| 欧美日韩中国免费专区在线看| 成人国产精品久久久久久亚洲| 欧美专区在线播放| 亚洲男人天堂九九视频| 国内精品一区二区三区| 欧美日韩精品中文字幕| 日本精品一区二区三区在线播放视频| 欧美黑人一级爽快片淫片高清| 日本久久中文字幕| 日韩在线视频中文字幕| 欧美午夜影院在线视频| 最近2019中文免费高清视频观看www99| 在线精品视频视频中文字幕| 午夜免费久久久久| 亚洲白虎美女被爆操| 九九热这里只有精品免费看| 国产视频欧美视频| 精品久久久国产精品999| 欧美黄网免费在线观看| 日韩在线国产精品| 国产精品美女免费视频| 亚洲色图第三页| 美女999久久久精品视频| 韩国精品久久久999| 91久久精品国产91久久性色| 亚洲午夜久久久久久久| 一区二区三区黄色| 亚洲影影院av| 久久亚洲国产精品成人av秋霞| 91av免费观看91av精品在线| 久久久日本电影| 日韩成人中文字幕| 久久精品国产亚洲7777| 欧美大人香蕉在线| 日韩av在线播放资源| 欧美日韩精品在线播放| 亚洲精品成人久久久| 午夜精品福利视频| 日本欧美在线视频| 欧美综合国产精品久久丁香| 欧美成人自拍视频| 亚洲成年网站在线观看| 欧美激情久久久久| 在线日韩av观看| 欧美高清不卡在线| 亚洲精品国产美女| 亚洲欧美日韩久久久久久| 98精品国产高清在线xxxx天堂| 国产视频久久久久| 亚洲国产精品yw在线观看| 欧美性高跟鞋xxxxhd| 久久精品小视频| 少妇高潮久久77777| 久久九九精品99国产精品| 欧美另类极品videosbestfree| 一区二区三区四区在线观看视频| 亚洲国产成人在线视频| 欧美日韩视频免费播放| 日韩在线激情视频| 欧美成人精品在线视频| 精品国产自在精品国产浪潮| 欧美激情在线视频二区| 色综久久综合桃花网| 成人激情免费在线| 色青青草原桃花久久综合| 国产精品流白浆视频| 色婷婷av一区二区三区在线观看| 色www亚洲国产张柏芝| 日韩欧美在线网址| 91成人免费观看网站| 久久视频国产精品免费视频在线| 日韩av电影手机在线观看| 日本欧美中文字幕| 午夜精品福利在线观看| 亚洲一区av在线播放| 国产香蕉97碰碰久久人人| 日韩国产欧美区| 欧美一级电影免费在线观看| 久久精品久久精品亚洲人| 亚洲精品久久久一区二区三区| 国产美女精品视频| 亚洲综合色av| 亚洲精品久久久久久久久久久| 日韩在线观看免费高清完整版| 亚洲最新中文字幕| 欧美激情在线狂野欧美精品| 日韩大片免费观看视频播放| 日产精品99久久久久久| 色噜噜国产精品视频一区二区| 日韩在线观看视频免费| 国产精品久久久久久久9999| 亚洲精品乱码久久久久久金桔影视| 精品福利视频导航| 国产精品对白刺激| 91久久精品国产91久久性色| 亚洲人在线观看| 日韩女优人人人人射在线视频| 青草热久免费精品视频| 国产精品吹潮在线观看| 日韩av一区在线观看| 亚洲第一精品夜夜躁人人躁| 国产成人亚洲综合| 国产成人97精品免费看片| 欧美精品在线免费| 日韩视频免费观看| 国产免费一区二区三区在线能观看| 精品久久久免费| 亚洲日本aⅴ片在线观看香蕉| 欧美一级淫片videoshd| 夜夜狂射影院欧美极品| 欧美老少配视频| 欧洲一区二区视频| 91午夜理伦私人影院| 中文字幕亚洲国产| 欧美成年人视频网站| xxxxx成人.com| 久久久久免费精品国产| 91在线视频成人| 中文字幕国产亚洲| 欧美视频在线视频| 欧美夫妻性生活xx| 国产精品久久久久久av下载红粉| 日韩动漫免费观看电视剧高清| 91在线免费视频| 亚洲欧美日韩中文在线| 成人精品视频久久久久| 久久91亚洲精品中文字幕奶水| 久久久久久久91| 日本中文字幕久久看| 日韩欧美高清在线视频| 日韩一区二区在线视频| 成人激情综合网| 97成人精品视频在线观看| 精品久久久久久中文字幕大豆网| 91精品国产自产91精品| 麻豆国产va免费精品高清在线| 日本亚洲欧洲色α| 国产精品中文字幕在线| 亚洲欧美综合图区| 亚洲剧情一区二区| 国产日韩欧美成人|