激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - Spring工廠方法創(chuàng)建(實(shí)例化)bean實(shí)例代碼

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

2021-03-17 14:06duanxz Java教程

這篇文章主要介紹了Spring工廠方法創(chuàng)建bean實(shí)例代碼,具有一定借鑒價(jià)值,需要的朋友可以參考下

目標(biāo)明確

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

思路清晰

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

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

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

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

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

注: 工廠類(lèi)實(shí)例沒(méi)有創(chuàng)建

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

方式:

<bean id="factory" class="工廠類(lèi)"/>

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

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

方法實(shí)用

示例1

需求:

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

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.spring.test.factorymethod;
 
public class Stage {
  public void perform(){
    System.out.println("演出開(kāi)始...");
  }
  private Stage(){
    
  }
  private static class StageSingletonHolder{
    static Stage instance = new Stage();
  }
  public static Stage getInstance(){
    return StageSingletonHolder.instance;
  }
}

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

?
1
2
3
4
5
6
7
8
<?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>

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

?
1
2
3
4
5
6
7
8
9
10
11
12
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é)果

?
1
2
3
4
5
6
7
一月 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
演出開(kāi)始...

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

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

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

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

?
1
2
3
public interface Animal {
  public void sayHello();
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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ì)模式。

?
1
2
3
4
5
6
7
8
9
public clas AnimalFactory {
  public static Animal getAnimal(String type){
    if ("cat".equalsIgnoreCase(type)){
      return new Cat();
    } else {
      return new Dog();
    }
  }
}

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- 配置AnimalFactory的getAnimal方法,使之產(chǎn)生Cat -->
<bean id="cat" class="com.abc.AnimalFactory" factory-method="getAnimal">
  <!-- 配置靜態(tài)工廠方法的參數(shù),getAnimal方法將產(chǎn)生Cat類(lèi)型的對(duì)象 -->
  <constructor-arg value="cat" />
  <!-- 通過(guò)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類(lèi)型的對(duì)象 -->
  <constructor-arg value="dog" />
  <!-- 通過(guò)setter注入的普通屬性 -->
  <property name="msg" value="狗狗" />
</bean>

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

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

?
1
2
3
4
5
6
7
8
9
10
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é)果:

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

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

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

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

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

當(dāng)我們指定Spring使用靜態(tài)工廠方法來(lái)創(chuàng)建Bean實(shí)例時(shí),Spring將先解析配置文件,并根據(jù)配置文件指定的信息,通過(guò)反射調(diào)用靜態(tài)工廠類(lèi)的靜態(tài)工廠方法,并將該靜態(tài)工廠方法的返回值作為Bean實(shí)例,在這個(gè)過(guò)程中,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)工廠方法只需要使用工廠類(lèi)即可,調(diào)用實(shí)例工廠方法則必須使用工廠實(shí)例。所以在Spring配置上也只有一點(diǎn)區(qū)別:配置靜態(tài)工廠方法指定靜態(tài)工廠類(lèi),配置實(shí)例工廠方法則指定工廠實(shí)例。同樣是上面的例子將AnimalFactory修改為:

?
1
2
3
4
5
6
7
8
9
public clas AnimalFactory {
  public Animal getAnimal(String type){ //這里僅僅是去掉了static關(guān)鍵字
    if ("cat".equalsIgnoreCase(type)){
      return new Cat();
    } else {
      return new Dog();
    }
  }
}

Spring文件修改為:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
<!-- 先配置工廠類(lèi) -->
<bean id="animalFactory" class="com.abc.AnimalFactory" />
<!-- 這里使用factory-bean指定實(shí)例工廠類(lèi)對(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è)試類(lèi)不用修改,輸出結(jié)果和上面相同。

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

配置工廠Bean的三種方式。

抽象接口:

?
1
2
3
public interface IMusicBox {
   public void play();
}

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

工廠類(lèi):

?
1
2
3
4
5
6
7
8
9
public class MusicBoxFactory {
  public static IMusicBox createMusicBox(){
  return new IMusicBox(){
       public void play(){
    System.out.println("Play piano...");
     }
  };
  }
}

配置文件:

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

測(cè)試類(lèi):

?
1
2
3
4
5
6
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í)例

工廠類(lèi):

?
1
2
3
4
5
6
7
8
9
public class MusicBoxFactory {
  public IMusicBox createMusicBox(){//沒(méi)有static修飾
  return new IMusicBox(){
       public void play(){
    System.out.println("Play piano...");
     }
  };
  }
}

配置文件:

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

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

測(cè)試類(lèi):

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

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

工廠類(lèi):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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;
  }
}

配置文件:

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

測(cè)試類(lèi):

?
1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
  ApplicationContext ctx = 
  new ClassPathXmlApplicationContext("bean-config.xml");
  //不加 & 返回工廠的“產(chǎn)品”
  IMusicBox musicbox = (IMusicBox)ctx.getBean("musicBox");
  musicbox.play();
  //加 & 返回工廠類(lèi)實(shí)例
  Object obj = ctx.getBean("&musicBox"); 
  System.out.println(obj.getClass().getName()); 
 
}

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

總結(jié)

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

原文鏈接:https://www.cnblogs.com/duanxz/p/3456948.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 九九热在线视频免费观看 | 精品国产乱码久久久久久预案 | 亚洲福利视频52 | 精品国产乱码久久久久久丨区2区 | 色综合久久久久综合99 | 免费黄色大片在线观看 | 精品亚洲二区 | 亚洲人成电影在线 | 国产91av视频 | 欧美成人一区二区三区电影 | 中文字幕免费看 | 一本色道久久99精品综合蜜臀 | 特片网久久| www亚洲| 中国成人在线视频 | 日韩精品一区二区久久 | 久久精品一级片 | 色羞羞| 国产一区网址 | 日本网站一区二区三区 | 国产精品欧美日韩一区二区 | 男女羞羞视频在线观看免费 | 色97在线| 一级观看免费完整版视频 | 性少妇chinesevideo | 羞羞网站在线观看入口免费 | 国产高潮好爽受不了了夜色 | www亚洲免费 | 黄色免费在线网址 | 美女久久久久 | 亚洲国产精品500在线观看 | 久久精品成人影院 | 亚洲日本韩国在线观看 | 国产九色在线播放九色 | 欧美精品成人一区二区在线观看 | 成人国产精品一区二区毛片在线 | h网站在线观看 | 精品亚洲午夜久久久久91 | 羞羞网站 | 国语自产免费精品视频在 | 男人天堂免费 |