工廠方法在Spring源碼中的運用

来源:https://www.cnblogs.com/tianClassmate/archive/2022/10/11/16779339.html
-Advertisement-
Play Games

我們都知道Spring中IOC是使用的工廠模式,但是對於實現細節就一知半解了,今天這篇文章就帶大家解讀Spring中是如何使用工廠模式的。 ...


我們都知道Spring中IOC是使用的工廠模式,但是對於實現細節就一知半解了,今天這篇文章就帶大家解讀Spring中是如何使用工廠模式的。

上篇文章中我們懂了什麼是工廠模式,這篇文章就帶著學過的概念深入到Spring的內部看看究竟是怎麼使用該模式的。

在Spring中使用工廠方法的是BeanFactory和FactoryBean<>介面。

一、BeanFactory使用工廠方法

使用了Spring框架,我們就很少自己進行對象的創建了,而我們使用到的對象當然就是交給Spring的工廠模式來創建的了。

其中BeanFactory是Spring容器的頂層介面,也是Bean工廠最上層的介面,其會有很多工廠實現例如ClassPathXmlApplicationContext、XmlWebApplicationContext其中最常見的就是DefaultListableBeanFactory,我們可以把BeanFactory看成是一種工廠方法模式。

image-20221011142530174

在工廠方法模式中有四個角色:

1、抽象工廠(Abstract Factory):提供了創建產品的介面,調用者通過它訪問具體工廠的工廠方法 createProduct() 來創建產品。

2、具體工廠(ConcreteFactory):主要是實現抽象工廠中的抽象方法,完成具體產品的創建。

3、抽象產品(Product):定義了產品的規範,描述了產品的主要特性和功能。

4、具體產品(ConcreteProduct):實現了抽象產品角色所定義的介面,由具體工廠來創建,它同具體工廠之間一一對應。

BeanFactory是角色中的抽象工廠,而getBean就相當於我們實例中的createProduct()方法,用於創建對象。

DefaultListableBeanFactory等實現的工廠類就是角色中的具體工廠。

產品就是在我們開發中加上註解的@Controller@Service@compent@Configuration的類,Spring會將他們當成產品使用工廠模式生成對象。

在我們createProduct方法中是直接創建的對象,Spring肯定不會這麼的笨,我們接著看getBean方法的實現方法。

getBean方法中一系列鏈路最終調用到doGetBean方法用於創建對象,在doGetBean中創建對象使用的是設計模式中的代理模式

二、FactoryBean<>使用工廠方法

講完BeanFactory,再介紹另外一個工廠模式的應用FactoryBean<>,想必大家也經常會比較這倆。

實際上,這兩個介面都是用於創建對象,都可以看做是工廠方法模式的實現。

FactoryBean<>工廠通過getObject()方法來創建並返回對象,我們可以通過實現FactoryBean<>來定製化自己需要的Bean對象。

image-20221011143719942

既然FactoryBean<>是留個開發者實現的,我們就手動實現一個FactoryBean<>。

@Component
public class MyFactoryBean<> implements FactoryBean<><Product>, BeanNameAware {
    private String name;
    @Override
    public Product getObject() throws Exception {
        return new Product();
    }

    @Override
    public Class<?> getObjectType() {
        return Product.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }

    @Override
    public void setBeanName(String s) {
        this.name = name;
    }
}

接著我們分別使用兩種方式getBean。

public static void main(String[] args) {

    //測試FactoryBean<>
    ApplicationContext ac =new AnnotationConfigApplicationContext(MyFactoryBean<>.class);

    System.out.println(ac.getBean("myFactoryBean<>"));

    System.out.println(ac.getBean("&myFactoryBean<>"));

}

只是在獲取Bean時加了一個&會出現兩種情況。

cn.sky1998.create.methodFactory.Product@52a86356
cn.sky1998.create.methodFactory.MyFactoryBean<>@5ce81285

doGetBean裡面進行了判斷是否是FactoryBean<>的實現類。

Spring對FactoryBean<>的實現機制是當你獲取一個Bean時,如果獲取的Bean的類型是FactoryBean<>,並且其name中並沒有&則調用bean的getObject方法獲取FactoryBean<>實現類中提供bean,否則就是直接返回普通的bean類型。

當我們在引入其他框架整合Spring時,便會有很多橋接整合包,例如mybatis-spring等,其中就會有FactoryBean<>的實現,例如SqlSessionFactoryBean<>、MapperFactoryBean<>等,將需要整合的定製化Bean通過工廠方法的模式,加入進Spring容器中。

當我們整合Mybatis時無論是多麼的Bean都能很好的處理,mybatis-spring中的FactoryBean<>正是將Mybatis的核心啟動類給調用出來。

三、BeanFactory和FactoryBean<>的異同

BeanFactory是Spring的一個大工廠,創建著Spring框架運行過程中所需要的Bean;

而FactoryBean<>是一個定製化工廠,其會存在於BeanFactory創建對象的過程中,當有需要時,會通過FactoryBean<>去自定製個性化的Bean,從而Spring框架提高擴展能力。

這篇文章加深工廠方法的理解的同時,又進一步的深入了BeanFactory和FactoryBean<>的實現細節。

設計模式相關博客:

概述

一、設計模式概述

創建型設計模式

二、設計模式之工廠方法和抽象工廠

三、設計模式之單例和原型

四、設計模式之建造者模式

結構型設計模式

五、設計模式之代理模式

六、設計模式之適配器模式

七、設計模式之橋接模式

八、設計模式之組合模式

九、設計模式之裝飾器模式

十、設計模式之外觀模式

十一、設計模式之享元模式

行為型設計模式

十二、設計模式之責任鏈模式

十三、設計模式之命令模式

十四、設計模式之解釋器模式

十五、設計模式之迭代器模式

十六、設計模式之中介者模式

十七、設計模式之備忘錄模式

十八、設計模式之觀察者模式

十九、設計模式之狀態模式

二十、設計模式之策略模式

二十一、設計模式之模板方法模式

二十二、設計模式之訪問者模式


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • StoneDB 的主從切換既可以手動切換,也可以自動切換,自動切換通常需要使用第三方中間件。本文介紹的是較為常用的中間件 Replication Manager,當 master 發生宕機時,可自動切換至 slave,保證業務正常運行,故障節點恢復後再加入主從。 伺服器配置說明 | IP | Mem ...
  • iOS ViewController 寫UIKit的代碼, ViewController是離不開的. 本文試圖講講它的基本知識, 不是很深入且有點雜亂, 供初級選手和跨技術棧同學參考. What is a View Controller iOS中的View Controller非常像Android中 ...
  • 雖然xcode現在可以免證書進行測試了,但眾多跨平臺開發者,如果還沒註冊蘋果開發者賬號。 想安裝到自己非越獄手機測試是無能為力了。 不過新技術來了,只需要普通免費的蘋果賬號無需付費成為開發者就可以申請iOS證書打包ipa安裝到自己手機測試! 沒付費蘋果開發者賬號的,也能輕鬆調試自己的蘋果APP。 當 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 第一題:說一下這三個div的佈局 <div class="parent"> <div class="child1">child1 content</div> <div class="child2">child2 content</div> ...
  • 1、將項目里的“node_modules”文件夾刪除,一般“node_modules”文件夾太大,一般不會打包上傳到svn、git上的,所以沒有這個文件夾就不用刪。 2、刪除package-lock.json。它是基於項目作者的npm版本庫生成的,如果不刪掉這個依賴文件,容易出現npm版本差異導致的 ...
  • 觀察者模式也可以理解為:發佈訂閱模式 發佈者狀態更新,通過管道介面實現訂閱者動態更新 1 class Middleware: 2 """ 3 發佈者和訂閱者交互類 4 0、訂閱者容器列表 5 1、包括訂閱者的增加、刪除 6 2、通過管道通知訂閱者 7 """ 8 9 def __init__(sel ...
  • 下午我被叫去參加“合作服務商資金安全解決方案”項目的codereview。對程式實現邏輯上存疑。簡單聽他們瞭解了一下需求邏輯。然後,果然發現邏輯有疏漏。為了表達清楚我的意思,上草圖。邊“畫”邊講。然後,大家點頭默許:還是戰哥想的全面! 在我們日常開發討論過程中,總會出現這樣的情況,你在講的頭頭是道, ...
  • 決策引擎是風控的大腦,而決策樹的編排能力和體驗是構建大腦的手段,如何構建高效、絲滑、穩定可靠的決策樹編排能力,是對風控決策引擎的一大挑戰,本篇文章和大家分享一下過往構建心得。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...