揭秘Spring Bean的生命脈搏:深度剖析構造方法的推斷藝術

1. 引言

在Spring框架中,Bean的生命周期是一個至關重要的概念。從Bean的創建、初始化到銷毀,每一個階段都承載著框架與用戶代碼的交互。而在Bean的創建階段,構造方法的推斷顯得尤為重要。本文將從源碼層面深入剖析Spring是如何推斷并選擇構造方法來完成Bean的實例化的。


2. Spring Bean的生命周期概述

在Spring中,Bean的生命周期大致可以分為以下幾個階段:實例化、屬性填充、初始化、使用和銷毀。其中,實例化階段就是通過某種方式(如構造器、工廠方法等)創建Bean的實例。而在這個階段,Spring需要確定使用哪個構造方法來創建Bean的實例。


3. 構造方法的推斷過程

  1. 確定候選構造器

    • Spring會首先收集目標類中所有的構造方法作為候選構造器。這包括私有構造器、公有構造器、默認構造器以及帶有參數的構造器等。
  2. 根據配置信息進行篩選

    • Spring會根據用戶在XML配置文件或注解中提供的配置信息來篩選候選構造器。例如,如果用戶在配置中指定了某個構造方法的參數值,那么Spring就會選擇這個構造方法來創建Bean的實例。
  3. 使用自動裝配進行推斷

    • 如果用戶沒有提供明確的構造方法參數配置,那么Spring會嘗試使用自動裝配機制來推斷應該使用哪個構造方法。具體來說,Spring會檢查每個構造方法的參數類型,并嘗試在Spring容器中查找與這些參數類型匹配的Bean。如果能夠找到匹配的Bean,并且這些Bean的數量與構造方法的參數數量一致,那么Spring就會選擇這個構造方法來創建Bean的實例。
  4. 默認構造器

    • 如果以上方法都無法確定應該使用哪個構造方法,那么Spring會默認使用無參構造器(如果存在)來創建Bean的實例。

4. 結合源碼分析

  1. 確定候選構造器
    • determineConstructorsFromBeanClass方法用于確定候選構造器。這個方法會獲取目標類的所有公共構造器(包括默認構造器),并返回一個構造器數組。如果類沒有公共構造器但有可訪問的默認構造器,也會包含它。如果連默認構造器都不可訪問(如私有的默認構造器且沒有公共構造器),則會拋出異常。

示例代碼片段(簡化版):

private Constructor<?>[] determineConstructorsFromBeanClass(Class<?> beanClass) {  if (beanClass.isInterface()) {  throw new BeanInstantiationException(beanClass, "Specified class is an interface");  }  try {  return beanClass.getDeclaredConstructors(); // 獲取所有聲明的構造器  } catch (Throwable ex) {  // 異常處理...  }  // ... 省略其他邏輯 ...  
}
  1. 篩選候選構造器
    • selectConstructor方法用于根據配置信息和自動裝配機制篩選候選構造器。這個方法會檢查每個構造器的參數,并嘗試找到與參數類型匹配的Bean定義。它還會考慮是否存在明確的參數值配置(如通過XML或注解配置)。

    • 如果配置文件中指定了構造方法的參數值,Spring會直接使用這些參數值來調用相應的構造方法。如果沒有指定參數值,但存在自動裝配的候選者,Spring會嘗試自動裝配。如果找到與構造方法參數類型完全匹配的Bean,并且數量與參數數量一致,Spring會選擇這個構造方法。

    • 如果既沒有明確的參數配置,也沒有找到匹配的自動裝配候選者,Spring會檢查是否存在默認構造器,并使用它(如果存在)。

示例代碼片段(簡化版):

private Constructor<?> selectConstructor(String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors) {  // 省略部分邏輯...  // 檢查是否有明確的構造器參數配置  if (mbd.hasConstructorArgumentValues()) {  // 嘗試匹配構造器參數...  }  // 如果沒有明確的配置,嘗試自動裝配  if (ctors.length == 1 && ctors[0].getParameterCount() == 0) {  return ctors[0]; // 只有一個無參構造器,直接返回  }  // 嘗試自動裝配匹配參數的構造器...  // 如果所有方法都失敗,且存在默認構造器,則返回默認構造器  if (mbd.resolveAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR &&  ctors.length != 0 && mbd.hasDefaultConstructor()) {  return ctors[0]; // 假設第一個是無參構造器(在實際情況中需要更準確的判斷)  }  // 如果所有方法都失敗,拋出異常  throw new BeanCreationException(...);  
}

注意:上述代碼片段是高度簡化的,實際的selectConstructor方法會涉及更多的邏輯和異常處理。

  1. 實例化Bean

    • 一旦確定了要使用的構造方法,Spring就會使用instantiateBean方法或類似的方法來創建Bean的實例。這通常涉及到反射調用選定的構造方法,并傳入必要的參數。
  2. 后續處理

    • Bean實例化之后,Spring還會進行屬性填充、初始化等操作,完成Bean的整個生命周期。

5. 總結

Spring Bean的構造方法推斷是一個復雜但重要的過程,它涉及到候選構造器的確定、篩選和實例化等多個步驟。通過深入了解這個過程的實現細節,我們可以更好地理解Spring框架的工作原理,并在實際開發中更好地利用它。


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/15379.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/15379.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/15379.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

程序員做副業項目,別把事情復雜化

賺錢&#xff0c;別把簡單的事情復雜化 不要把簡單的事情復雜化。在大多數情況下&#xff0c;你并不需要一個應用程序、一個小程序、一個公眾號、一個微商城、編寫深度文章、建立一個社群&#xff0c;甚至不需要所謂的個人品牌、IP或運營技巧。 你只需要一個裝滿5000個&#…

Linux基礎(五):常用基本命令

從本節開始&#xff0c;我們正式進入Linux的學習&#xff0c;通過前面的了解&#xff0c;我們知道我們要以命令的形式使用操作系統&#xff08;使用操作系統提供的各類命令&#xff0c;以獲得字符反饋的形式去使用操作系統。&#xff09;&#xff0c;因此&#xff0c;我們是很有…

python將多個音頻文件與一張圖片合成視頻

代碼中m4a可以換成mp3,圖片和音頻放同一目錄&#xff0c;圖片名image.jpg&#xff0c;多線程max_workers可以根據CPU核心數量修改。 import os import subprocess import sys import concurrent.futures import ffmpeg def get_media_duration(media_path): probe ffmp…

Linkis踩坑記錄

從WeDataSphere的docker鏡像中把代碼和配置拷貝到普通環境運行&#xff0c;結果linkis提交任務總是報錯&#xff1a; Failed to execute task TaskID_1_otJobI d_astJob_0_codeExec_0 org.apache.linkis.orchestrator.ecm.exception.ECMPluginErrorException: errCode: 12003 …

【全開源】點餐小程序系統源碼(ThinkPHP+FastAdmin+UniApp)

基于ThinkPHPFastAdminUniApp開發的點餐微信小程序&#xff0c;類似肯德基&#xff0c;麥當勞&#xff0c;喜茶等小程序多店鋪模式&#xff0c;支持子商戶模式&#xff0c;提供全部前后臺無加密源代碼和數據庫&#xff0c;支持私有化部署。 革新餐飲行業的智慧點餐解決方案 一…

【vue-6】監聽

一、監聽watch 完整示例代碼&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Documen…

【MATLAB源碼-第213期】基于matlab的16QAM調制解調系統軟硬判決對比仿真,輸出誤碼率曲線對比圖。

操作環境&#xff1a; MATLAB 2022a 1、算法描述 一、16QAM調制原理 在16QAM&#xff08;16 Quadrature Amplitude Modulation&#xff09;調制中&#xff0c;一個符號表示4個比特的數據。這種調制方式結合了幅度調制和相位調制&#xff0c;能夠在相同的頻譜資源下傳輸更多…

【Java基礎】IO流(5) —— 序列流、內存流

【Java基礎】IO流(1) —— 簡介 【Java基礎】IO流(2) —— 字符流 【Java基礎】IO流(3) —— 字節流 【Java基礎】IO流(4) —— 轉換流、打印流 【Java基礎】IO流(5) —— 序列流、內存流 【Java基礎】IO流(6) —— 隨機訪問文件流、數據流 序列流 SequenceInputStream 序列…

EEGLAB的相關使用

目錄 概念 1.安裝EEGLAB 2.文件實例演示 導入數據集處理 &#xff08;1&#xff09;導入數據集 &#xff08;2&#xff09;畫圖 &#xff08;3&#xff09; 修改并存儲數據集 &#xff08;4&#xff09; 保存數據集 &#xff08;5&#xff09; 刪除數據集 &#xff0…

技術前沿 |【BLIP:統一理解和生成的自舉多模態模型研究】

BLIP&#xff1a;統一理解和生成的自舉多模態模型研究 摘要引言一、BLIP模型概述二、 BLIP模型在多模態任務中的應用三、總結 摘要 本文介紹了BLIP&#xff08;Bootstrapping Language-Image Pre-training&#xff09;模型&#xff0c;一個前沿的多模態模型&#xff0c;通過自…

散列(哈希)及其練習題(基礎)

目錄 散列 字符出現次數 力扣經典題&#xff1a;兩數之和 集合運算 交 并 差 字符串的出現次數 散列 導入&#xff1a; 有N個數和M個數&#xff0c;如何判斷M個數中每個數是否在N中出現&#xff1f; 思想&#xff1a;空間換時間 創建hashtable&#xff0c;以N個數本…

圖_基礎算法

圖這種數據結構還有一些比較特殊的算法&#xff0c;比如二分圖判斷&#xff0c;有環圖無環圖的判斷&#xff0c;拓撲排序&#xff0c;以及最經典的最小生成樹&#xff0c;單源最短路徑問題&#xff0c;更難的就是類似網絡流這樣的問題。 先看拓撲排序&#xff08;有環無環&…

【linux性能分析】heaptrack分析內存占用

文章目錄 1. Heaptrack是什么2. Heaptrack有哪些功能3. Heaptrack和valgrind massif對比4. Heaptrack安裝5. Heaptrack生成追蹤文件6. heaptrack_gui進行內存分析7. heaptrack_print也能用于堆分析8. 報錯解決9. 補充介紹&#xff1a;heaptrack編譯安裝 1. Heaptrack是什么 he…

內網穿透--Spp-特殊協議-上線

免責聲明:本文僅做技術交流與學習... 目錄 spp項目: 一圖通解: 1-下載spp 2-服務端執行命令 3-客戶端執行命令 4-服務端cs監聽&生馬 spp項目: GitHub - esrrhs/spp: A simple and powerful proxy 支持的協議&#xff1a;tcp、udp、udp、icmp、http、kcp、quic 支持的…

Java開發者必知的時間處理工具:SimpleDateFormat類詳解

哈嘍&#xff0c;各位小伙伴們&#xff0c;你們好呀&#xff0c;我是喵手。運營社區&#xff1a;C站/掘金/騰訊云&#xff1b;歡迎大家常來逛逛 今天我要給大家分享一些自己日常學習到的一些知識點&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相學習&#xff0c;一…

使用兩塊ESP8266實現ESP-NOW通信

ESP-NOW簡介 ESP-NOW是Espressif開發的一種基于Wi-Fi的低功耗通信協議。與傳統Wi-Fi通信不同&#xff0c;ESP-NOW不需要配對過程&#xff0c;設備間可以直接通信&#xff0c;非常適合需要快速傳輸小數據包的應用&#xff0c;如傳感器網絡、遙控器和智能家居設備。它的優勢在于…

小紅書云原生 Kafka 技術剖析:分層存儲與彈性伸縮

面對 Kafka 規模快速增長帶來的成本、效率和穩定性挑戰時&#xff0c;小紅書大數據存儲團隊采取云原生架構實踐&#xff1a;通過引入冷熱數據分層存儲、容器化技術以及自研的負載均衡服務「Balance Control」&#xff0c;成功實現了集群存儲成本的顯著降低、分鐘級的集群彈性遷…

[圖解]SysML和EA建模住宅安全系統-07 to be塊定義圖

1 00:00:01,970 --> 00:00:05,040 入侵者這里有個∞ 2 00:00:05,530 --> 00:00:07,000 說明它下面已經有子圖了 3 00:00:07,010 --> 00:00:08,080 我們看看里面子圖 4 00:00:10,200 --> 00:00:17,000 這里&#xff0c;我們看位置 5 00:00:19,030 --> 00:00:…

Vitis HLS 學習筆記--抽象并行編程模型-不良示例

目錄 1. 簡介 2. 基礎 kernel 2.1 pass kernel 2.2 double_pass kernel 2.3 add_kernel 2.4 split kernel 3. 三種bypass 3.1 input_bypass 3.2 middle_bypass 3.3 output_bypass 4. 總結 1. 簡介 本文展示三個在數據流水線中常見的問題&#xff1a; 輸入參數繞過…

python中模擬鍵盤按鍵和鼠標按鍵

目錄 0.作用和需安裝庫 1.模擬鍵盤按鍵 2.虛擬鍵表 3.模擬鼠標 0.作用和需安裝庫 作用&#xff1a;用程序實現達到按下鍵盤按鍵的作用&#xff0c;或者按下鼠標&#xff0c;無需真正按鍵盤或者鼠標。 需要安裝pywin32這個庫 pip install pywin32 1.模擬鍵盤按鍵 例子1…