【死磕 Spring】----- IOC 之解析 bean 標簽:解析自定義標簽

前面四篇文章都是分析 Bean 默認標簽的解析過程,包括基本屬性、六個子元素(meta、lookup-method、replaced-method、constructor-arg、property、qualifier),涉及內容較多,拆分成了四篇文章,導致我們已經忘記從哪里出發的了,勿忘初心

processBeanDefinition() 負責 Bean 標簽的解析,在解析過程中首先調用BeanDefinitionParserDelegate.parseBeanDefinitionElement() 完成默認標簽的解析,如果解析成功(返回的 bdHolder != null ),則首先調用 BeanDefinitionParserDelegate.decorateBeanDefinitionIfRequired() 完成自定義標簽元素解析,前面四篇文章已經分析了默認標簽的解析,所以這篇文章分析自定義標簽的解析。

 
  1. public BeanDefinitionHolder decorateBeanDefinitionIfRequired(Element ele, BeanDefinitionHolder definitionHolder) {

  2. return decorateBeanDefinitionIfRequired(ele, definitionHolder, null);

  3. }

調用 decorateBeanDefinitionIfRequired()

 
  1. public BeanDefinitionHolder decorateBeanDefinitionIfRequired(

  2. Element ele, BeanDefinitionHolder definitionHolder, @Nullable BeanDefinition containingBd) {


  3. BeanDefinitionHolder finalDefinition = definitionHolder;


  4. // 遍歷節點,查看是否有適用于裝飾的屬性

  5. NamedNodeMap attributes = ele.getAttributes();

  6. for (int i = 0; i < attributes.getLength(); i++) {

  7. Node node = attributes.item(i);

  8. finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);

  9. }


  10. // 遍歷子節點,查看是否有適用于修飾的子元素

  11. NodeList children = ele.getChildNodes();

  12. for (int i = 0; i < children.getLength(); i++) {

  13. Node node = children.item(i);

  14. if (node.getNodeType() == Node.ELEMENT_NODE) {

  15. finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);

  16. }

  17. }

  18. return finalDefinition;

  19. }

遍歷節點(子節點),調用 decorateIfRequired() 裝飾節點(子節點)。

 
  1. public BeanDefinitionHolder decorateIfRequired(

  2. Node node, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd) {

  3. // 獲取自定義標簽的命名空間

  4. String namespaceUri = getNamespaceURI(node);

  5. // 過濾掉默認命名標簽

  6. if (namespaceUri != null && !isDefaultNamespace(namespaceUri)) {

  7. // 獲取相應的處理器

  8. NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);

  9. if (handler != null) {

  10. // 進行裝飾處理

  11. BeanDefinitionHolder decorated =

  12. handler.decorate(node, originalDef, new ParserContext(this.readerContext, this, containingBd));

  13. if (decorated != null) {

  14. return decorated;

  15. }

  16. }

  17. else if (namespaceUri.startsWith("http://www.springframework.org/")) {

  18. error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", node);

  19. }

  20. else {

  21. if (logger.isDebugEnabled()) {

  22. logger.debug("No Spring NamespaceHandler found for XML schema namespace [" + namespaceUri + "]");

  23. }

  24. }

  25. }

  26. return originalDef;

  27. }

首先獲取自定義標簽的命名空間,如果不是默認的命名空間則根據該命名空間獲取相應的處理器,最后調用處理器的 decorate() 進行裝飾處理。具體的裝飾過程這里不進行講述,在后面分析自定義標簽時會做詳細說明。

至此,Bean 的解析過程已經全部完成了,下面做一個簡要的總結。

解析 BeanDefinition 的入口在 DefaultBeanDefinitionDocumentReader.parseBeanDefinitions() 。該方法會根據命令空間來判斷標簽是默認標簽還是自定義標簽,其中默認標簽由 parseDefaultElement() 實現,自定義標簽由 parseCustomElement() 實現。在默認標簽解析中,會根據標簽名稱的不同進行 import 、alias 、bean 、beans 四大標簽進行處理,其中 bean 標簽的解析為核心,它由 processBeanDefinition() 方法實現。 processBeanDefinition() 開始進入解析核心工作,分為三步:

  1. 解析默認標簽: BeanDefinitionParserDelegate.parseBeanDefinitionElement()

  2. 解析默認標簽下的自定義標簽: BeanDefinitionParserDelegate.decorateBeanDefinitionIfRequired()

  3. 注冊解析的 BeanDefinition: BeanDefinitionReaderUtils.registerBeanDefinition

在默認標簽解析過程中,核心工作由 parseBeanDefinitionElement() 方法實現,該方法會依次解析 Bean 標簽的屬性、各個子元素,解析完成后返回一個 GenericBeanDefinition 實例對象。


原文發布時間為:2018-09-26
本文作者:Java技術驛站
本文來自云棲社區合作伙伴“Java技術驛站”,了解相關信息可以關注“Java技術驛站”。

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

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

相關文章

Codeigniter 4.0-dev 版源碼學習筆記之四——詳細路由過程

前言 我個人覺得在當前 MVC 流行的架構下&#xff0c;要想去了解一個框架&#xff0c;或者是一個基于此架構下的應用程序&#xff0c;最好的入手方式就是先看路由&#xff0c;雖然路由不是 MVC 里的任何一個&#xff0c;但是知道了路由的來龍去脈就知道了整個框架或者是應用的結…

固態硬盤和機械硬盤的比較和SQLSERVER在兩種硬盤上的性能差異

聽說固態硬盤是高富帥的必備神器&#xff0c;本人為了提升工作效率和提高工作速度 這個月節衣縮食&#xff0c;終于也決定買了一塊三星固態硬盤120G容量 這個固態硬盤拿在手里輕飄飄的&#xff0c; 好像里面什么東西都沒有似的 廢話少說&#xff0c;先上圖 開機速度20秒左右 測…

大文件讀寫效率比較

之前做到一個大日志文件&#xff08;size > 1G&#xff09;解析的項目&#xff0c;在此記錄下對于大文本解析方式的效率比較。不同方式的性能差別很大&#xff0c;那個項目的日志解析時間能從原來的超過36小時優化到只需要2分鐘&#xff0c;awk功不可沒。 bash 比較 bash腳本…

python裝飾器執行順序

2019獨角獸企業重金招聘Python工程師標準>>> 1、單個裝飾器執行 上來先看代碼&#xff1a; import timedef deco(func):functools.wraps(func)def _wrapper():startTime time.time()print "start"func()print "end"endTime time.time()msecs …

tomcat限制用域名訪問 禁止 ip訪問

有時候會遇到服務器網站。只可以通過域名訪問。而不允許ip訪問。防止域名惡意解析&#xff0c;tomcat可以實現這個簡單功能。1&#xff0c;禁止ip訪問項目 2&#xff0c;只允許綁定域名訪問環境&#xff1a;tomcat7 外網地址&#xff1a;114.113.100.166 域名&#xff1a;bi…

Object關于屬性property的靜態方法

Object.defineProperty Object.defineProperty(obj, prop, { value: undefined, enumerable: true, writable:true, get: function() {return value}, set: function(newValue) {value newValue;} }) 當時配置了set和get時&#xff0c;則不能配置value。 Object.getOwnPropert…

99. Recover Binary Search Tree

一、題目 1、審題 2、分析 給出一個二叉查找樹&#xff0c;其中有兩個元素的位置弄錯了&#xff0c;寫算法將其恢復。 二、解答 1、思路&#xff1a; 方法一、 通過中序遍歷可以確定一棵二叉查找樹由小到大的順序。 所以在此錯位的查找樹中查找到的節點中有 1 個比后續節點值大…

myeclipse+git pull項目報錯

2019獨角獸企業重金招聘Python工程師標準>>> 1.在本地工程目錄(.git)找到config文件&#xff1b; 2.修改config文件內容為&#xff1a; [core] repositoryformatversion 0 filemode false logallrefupdates true [branch "master"] remote origin m…

luoguP4755 Beautiful Pair

https://www.luogu.org/problemnew/show/P4755 考慮分治&#xff0c;在 [l, r] 區間中用線段樹找到最大的一個點&#xff0c;處理經過它的可行數對的個數&#xff0c;統計個數可以離線樹狀數組處理 因為最多被分成 2n 個區間&#xff08;像線段樹一樣&#xff09;&#xff0c;對…

如何關掉macbook的開機聲音

1、系統偏好設置->聲音 2、關掉“啟動時播放聲音” 這樣設置之后&#xff0c;macbook再開機就沒有“咚”的那個聲音了

oatdata結構詳解

段名稱 文件內偏移段大小ELF頭部0x000000000x00001000oatdata0x000010000x027b8000oatexec0x027b90000x01ed69ecELF尾部0x046900000x00001000OatHeader&#xff1a; 0x00001000 | 6F 61 74 0A 30 33 39 00 77 40 00 B1 03 00 00 00 | 0x00001010 | 01 00 00 00 19 00 00 00 00…

【躍遷之路】【599天】程序員高效學習方法論探索系列(實驗階段356-2018.09.27)...

(躍遷之路)專欄 實驗說明 從2017.10.6起&#xff0c;開啟這個系列&#xff0c;目標只有一個&#xff1a;探索新的學習方法&#xff0c;實現躍遷式成長實驗期2年&#xff08;2017.10.06 - 2019.10.06&#xff09;我將以自己為實驗對象。我將開源我的學習方法&#xff0c;方法不斷…

開源 java CMS - FreeCMS2.6 Web頁面信息采集

2019獨角獸企業重金招聘Python工程師標準>>> java開源論壇系統http://javabbs.javaz.cn 項目地址&#xff1a;http://www.freeteam.cn/ Web頁面信息采集 從FreeCMS 2.1開始支持 通過簡單配置即可抓取目標網頁信息&#xff0c;支持增量式采集、關鍵字替換、定時采集&…

PropertySource和ConfigurationProperties

https://blog.csdn.net/u013725455/article/details/79352459轉載于:https://www.cnblogs.com/qunincey/p/9721364.html

ORACLE關于段的HEADER_BLOCK的一點淺析

在學習段&#xff08;segment&#xff09;、區間&#xff08;extent&#xff09;時&#xff0c;對段的HEADER_BLOCK有一些疑問&#xff0c;本文記錄一下探究的實驗過程以及相關總結&#xff0c;&#xff0c;如有不對的地方&#xff0c;敬請指出。以SCOTT.EMP表為例&#xff08;…

【源碼探索】.NET中的List,為什么即有Count屬性又有Count()方法

“優秀的程序員的標準之一是&#xff1a;編寫更易于擴展的代碼”圖片&#xff1a;奧森公園的向日葵 拍攝于2022年7月23日01—問題緣起上一篇中&#xff0c;我們知道List<T>的是基于數組實現的可變長度的列表。很多小伙伴發現&#xff0c;List<T>即有Count屬性又有C…

使用ASP.NET廣告控件的XML語言創建廣告鏈接--ASP.NET

1、AdRotator廣告控件的所有屬性都是可選的&#xff0c;XML文件中可以包含如下表所示的屬性&#xff08;XML文件的廣告屬性&#xff09;。 屬性 說明 ImageUrl 要顯示的圖像的URL NavigateUrl 單擊AdRotator控件時要轉到的網頁URL AlternateText 圖像不可用時現實的問…

vim編輯和命令模式、實踐

2019獨角獸企業重金招聘Python工程師標準>>> 9月29日任務 5.5 進入編輯模式 5.6 vim命令模式 5.7 vim實踐 Vim編輯模式 進入編輯模式 操作 說明 i 在光標所在字符前插入內容 I 在光標所在行行首插入內容 a 在光標所在字符后插入內容 A 在光標所在行行尾插入…

英語自動提取高頻詞_斑馬英語提分營免費體驗課

斑馬英語電腦版是一款專業可靠的英語學習軟件&#xff0c;斑馬英語官方版可以幫助孩子學習純正的英語口語發音&#xff0c;以講故事的形式讓孩子學習單詞及口語練習&#xff0c;斑馬英語電腦版針對兒童語言特征設計的智能口語測評系統&#xff0c;能夠自動識別發音和評分&#…

【C# Personal Handbook】開篇

博客已提更一年多了&#xff0c;這段時間里&#xff0c;發生了很多事情&#xff0c;也讓我對C#更加依戀&#xff0c;所以我決定重新更新博客&#xff0c;以自己的實踐經驗梳理C#的技術脈絡&#xff0c;也歡迎大家手下留情&#xff0c;耐心指點&#xff0c;讓我們共同進步吧&…