亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

深入了解Spring中的FactoryBean

 更新時間:2019年09月04日 08:17:47   作者:OKevin  
這篇文章主要介紹了深入了解Spring中的FactoryBean,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

FactoryBeanBeanFactory由于在命名上極其相似,一直以來困擾了不少的開發(fā)者。

BeanFactory,耳熟能詳?shù)腟pring核心接口,提供IoC容器的最基本功能。但要解釋FactoryBean一句話可能就說不清楚了。我們將從下面的例子逐步說明,F(xiàn)actoryBean是什么,它提供了什么樣的能力。

/**
 * 布料
 * 包含顏色屬性
 * Created by OKevin On 2019/9/3
 **/
public class Cloth {
 private Red red;
 //省略setter/getter方法
}

當初始化一個Cloth對象時,我希望Red對象也被賦值,此時我將在Cloth的構(gòu)造方法中new一個Red對象。

public Cloth() {
 red = new Red();
}

但是隨著業(yè)務的發(fā)展,我希望Cloth的顏色屬性將是Blue藍色,這時我將修改代碼將Red和Blue類抽象出一個Color接口,Cloth代碼將重構(gòu):

/**
 * 布料
 * 包含顏色屬性
 * Created by OKevin On 2019/9/3
 **/
public class Cloth {
 private Color color;
 public Cloth() {
  color = new Blue();
 }
 //省略setter/getter方法
}

業(yè)務又進一步發(fā)展,Cloth類中的顏色屬性將會根據(jù)一定的條件賦值為Red紅色,此時我們將代碼繼續(xù)重構(gòu):

/**
 * 布料
 * 包含顏色屬性
 * Created by OKevin On 2019/9/3
 **/
public class Cloth {
 private Color color;
 public Cloth() {
  if (condition()) {
   color = new Blue(); 
  } else {
   color = new Red();
  }
 }
 //省略setter/getter方法
}

這樣的代碼的確能運行,但如果有新的條件繼續(xù)加入到業(yè)務中,此時我們又將改動Cloth類的構(gòu)造方法,而我們認為Cloth方法是一個比較核心的業(yè)務對象,不應該經(jīng)常對它進行修改,并且在構(gòu)造方法中對于Color對象創(chuàng)建過于冗余,不符合單一職責的原則,所以我們將Color對象的創(chuàng)建過程通過工廠方法模式來完成。

靜態(tài)工廠方法

我們再次將Cloth類進行如下重構(gòu)(為了使示例代碼更加簡潔,下面的示例將只創(chuàng)建Red對象):

/**
 * 布料
 * 包含顏色屬性
 * Created by OKevin On 2019/9/3
 **/
public class Cloth {
 private Color color;
 public Cloth() {
  color = StaticColorFactory.newInstance();
 }
 //省略setter/getter方法
}
/**
 * 靜態(tài)工廠方法
 * Created by OKevin On 2019/9/3
 **/
public class StaticColorFactory {
 public static Color getInstance() {
  return new Red();
 }
}

如果我們在Spring容器中要通過靜態(tài)工廠方法,創(chuàng)建具體的對象實例應該怎么做呢?

眾所周知,要將一個對象實例交由Spring容器管理,我們通常是通過以下XML配置:

<bean id="cloth" class="com.coderbuff.bean.Cloth">
 <property name="color" ref="red"/>
</bean>
<bean id="red" class="com.coderbuff.bean.Red" />

但此時,Red對象實例并不是由Spring容器管理,而是由靜態(tài)工廠方法創(chuàng)建的,此時我們應該講XML配置修改為以下方式:

<bean id="cloth" class="com.coderbuff.bean.Cloth">
 <property name="color" ref="red"/>
</bean>
<bean id="red" class="com.coderbuff.factory.StaticColorFactory" factory-method="getInstance" />

這是Spring支持靜態(tài)工廠方法創(chuàng)建對象實例的特定方式。這樣我們就能在Spring中通過靜態(tài)工廠方法創(chuàng)建對象實例。

實例工廠方法

有靜態(tài)工廠方法,就有非靜態(tài)工廠方法,區(qū)別就是方法不是靜態(tài)的。

/**
 * 實例工廠方法
 * Created by OKevin On 2019/9/3
 **/
public class ColorFactory {
 public Color getInstance() {
  return new Red();
 }
}

實例工廠方法在Spring中XML配置略有不同:

<bean id="cloth" class="com.coderbuff.bean.Cloth">
 <property name="color" ref="red"/>
</bean>
<bean id="colorFactory" class="com.coderbuff.factory.ColorFactory"/>
<bean id="red" factory-bean="colorFactory" factory-method="getInstance"/>

通過配置可以看到,我們需要首先在Spring中實例化工廠,再通過工廠對象實例化Red對象。

在有了對工廠方法在Spring中創(chuàng)建對象實例的認識后,F(xiàn)actoryBean實際上就是為我們簡化這個操作。下面我們將通過FactoryBean來創(chuàng)建Red對象。

FactoryBean

/**
 * Created by OKevin On 2019/9/3
 **/
public class ColorFactoryBean implements FactoryBean<Color> {
 public Color getObject() throws Exception {
  return new Red();
 }
 public Class<?> getObjectType() {
  return Red.class;
 }
 public boolean isSingleton() {
  return false;
 }
}

通過實現(xiàn)FactoryBean的方式,XML配置如下:

<bean id="cloth" class="com.coderbuff.bean.Cloth">
 <property name="color" ref="red"/>
</bean>
<bean id="red" class="com.coderbuff.factory.ColorFactoryBean"/>

這樣就不用像工廠方法那樣配置相應的屬性,直接按照普通的Bean注入即可,由于Spring內(nèi)部做了特殊處理,此時名稱為“red”的Bean并不是ColorFactoryBean,而是它方法中g(shù)etObject中返回的對象。如果實在想要獲取ColorFactoryBean的對象實例,則在Bean的名稱前加入“&”即可(“&red”)。

看到這里,是否對FactoryBean有了一點認識呢?FactoryBean在Spring中最為典型的一個應用就是用來創(chuàng)建AOP的代理對象。

我們知道AOP實際上是Spring在運行時創(chuàng)建了一個代理對象,也就是說這個對象,是我們在運行時創(chuàng)建的,而不是一開始就定義好的,這很符合工廠方法模式。更形象地說,AOP代理對象通過Java的反射機制,在運行時創(chuàng)建了一個代理對象,在代理對象的目標方法中根據(jù)業(yè)務要求織入了相應的方法。這個對象在Spring中就是——ProxyFactoryBean。

ProxyFactoryBean

我們將通過比較“古老”的方式創(chuàng)建一個Red對象的切面,在它的print方法執(zhí)行前和執(zhí)行后分別執(zhí)行一條語句。之所以古老是因為我們往往通過注解的方式,而不會這么折磨自己去寫一個切面對象。

/**
 * 環(huán)繞通知
 * Created by OKevin On 2019/9/4
 **/
public class LogAround implements MethodInterceptor {
 public Object invoke(MethodInvocation invocation) throws Throwable {
  System.out.println("調(diào)用目標方法【前】打印日志");
  Object result = invocation.proceed();
  System.out.println("調(diào)用目標方法【后】打印日志");
  return result;
 }
}

此時我們需要ProxyFactoryBean的介入為我們創(chuàng)建一個代理對象并由Spring容器管理,根據(jù)上面ColorFactoryBean的經(jīng)驗,ProxyFacoryBean也應該如下配置:

<bean id="xxx" class="org.springframework.aop.framework.ProxyFactoryBean" />

答案是肯定的,只是ProxyFactoryBean多了幾個參數(shù),既然是生成代理對象,那么目標對象、目標方法就必不可少,實際的XLM配置如下:

<bean id="logAround" class="com.coderbuff.aop.LogAround"/>
<bean id="red" class="com.coderbuff.bean.Red"/>
<bean id="proxyRed" class="org.springframework.aop.framework.ProxyFactoryBean">
 <property name="proxyInterfaces" value="com.coderbuff.bean.Color"/>
 <property name="interceptorNames" value="logAround"/>
 <property name="target" ref="red"/>
 <property name="proxyTargetClass" value="true"/>
</bean>

通過測試程序,ProxyFactoryBean的確生成了一個代理對象。

public class ProxyFactoryBeanTest {
 private ClassPathXmlApplicationContext ctx;
 @Before
 public void init() {
  ctx = new ClassPathXmlApplicationContext("spring-proxyfactorybean.xml");
 }
 @Test
 public void testProxyFactory() {
  Red proxyRed = (Red) ctx.getBean("proxyRed");
  proxyRed.print();
 }
}

所以,F(xiàn)actoryBean為我們實例化Bean提供了一個更為靈活的方式,我們可以通過FactoryBean創(chuàng)建出更為復雜的Bean實例。

本文完整代碼地址:https://github.com/yu-linfeng/BlogRepositories/tree/master/repositories/factorybean

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 深入理解hibernate的三種狀態(tài)

    深入理解hibernate的三種狀態(tài)

    本篇文章主要介紹了深入理解hibernate的三種狀態(tài) ,主要包括了transient(瞬時狀態(tài)),persistent(持久化狀態(tài))以及detached(離線狀態(tài)),有興趣的同學可以了解一下
    2017-05-05
  • Spring源碼完美導入IDEA的過程

    Spring源碼完美導入IDEA的過程

    正值春節(jié)假期,小伙伴私信我idea導入spring源碼的過程,今天抽空給大家整理一篇教程幫助大家學習Spring源碼完美導入IDEA的詳細過程,感興趣的朋友一起看看吧
    2022-02-02
  • Java面試題沖刺第二十八天--數(shù)據(jù)庫(5)

    Java面試題沖刺第二十八天--數(shù)據(jù)庫(5)

    這篇文章主要為大家分享了最有價值的三道關(guān)于數(shù)據(jù)庫的面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-09-09
  • SpringBoot集成Swagger2的方法

    SpringBoot集成Swagger2的方法

    這篇文章主要介紹了SpringBoot集成Swagger2的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • SpringBoot如何配置Controller實現(xiàn)Web請求處理

    SpringBoot如何配置Controller實現(xiàn)Web請求處理

    這篇文章主要介紹了SpringBoot如何配置Controller實現(xiàn)Web請求處理,文中通過圖解示例介紹的很詳細,具有有一定的參考價值,需要的小伙伴可以參考一下
    2023-05-05
  • 基于IO版的用戶登錄注冊實例(Java)

    基于IO版的用戶登錄注冊實例(Java)

    下面小編就為大家?guī)硪黄贗O版的用戶登錄注冊實例(Java)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • 解決springboot中@DynamicUpdate注解無效的問題

    解決springboot中@DynamicUpdate注解無效的問題

    這篇文章主要介紹了解決springboot中@DynamicUpdate注解無效的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java實現(xiàn)微信企業(yè)付款到個人功能

    java實現(xiàn)微信企業(yè)付款到個人功能

    這篇文章主要為大家詳細介紹了java實現(xiàn)微信企業(yè)付款到個人功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • jenkins配置詳細指南(附j(luò)dk多個版本配置)

    jenkins配置詳細指南(附j(luò)dk多個版本配置)

    Jenkins是一款CICD(持續(xù)集成與持續(xù)交付)工具,Jenkins可以幫你在寫完代碼后,一鍵完成開發(fā)過程中的一系列自動化部署的工作,這篇文章主要給大家介紹了關(guān)于jenkins配置的相關(guān)資料,文中還附j(luò)dk多個版本配置指南,需要的朋友可以參考下
    2024-02-02
  • Java的Struts框架中<results>標簽的使用方法

    Java的Struts框架中<results>標簽的使用方法

    這篇文章主要介紹了Java的Struts框架中<results>標簽的使用方法,Struts框架是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下
    2015-11-11

最新評論