看Spring源碼不得不會的@Enable模塊驅動實現原理講解

来源:https://www.cnblogs.com/zzyang/archive/2022/05/28/16320696.html
-Advertisement-
Play Games

這篇文章我想和你聊一聊 spring的@Enable模塊驅動的實現原理。 在我們平時使用spring的過程中,如果想要加個定時任務的功能,那麼就需要加註解@EnableScheduling,如果想使用非同步的功能,那就要加@EnableScheduling註解,其實這類註解就是屬於@Enable模塊。 ...


這篇文章我想和你聊一聊 spring的@Enable模塊驅動的實現原理。

在我們平時使用spring的過程中,如果想要加個定時任務的功能,那麼就需要加註解@EnableScheduling,如果想使用非同步的功能,那就要加@EnableScheduling註解,其實這類註解就是屬於@Enable模塊。

那麼@Enable模塊到底有什麼功能?

模塊是指具備相同領域的功能組件集合,組合所形成一個獨立的單元。比如Web MVC模塊、AspectJ代理模塊Caching緩存模塊,JMX(Java管理擴展)、Async非同步處理模塊等。所謂模塊裝配,簡而言之就是,通過@EnableXXX註解實現一個開關,這個開關決定是否開啟某個功能模塊的所有組件的自動化配置。

那麼@EnableXXX註解是如何生效的?

其實@EnableXXX只是一個名字,通過這個名字讓人知道實現了什麼功能,其實這個註解叫什麼名字其實是無所謂的,就算不叫@EnableXXX都行,只不過spring內部都叫@EnableXXX,我們就習慣叫@Enable模塊,所以核心不是這個註解,而是註解實現的套路。

接下來我們來說說這個註解功能實現的套路

一般@EnableXXX註解是通過@Import實現具體的功能(@EnableXXX註解上加個@Import註解),@Import才是@EnableXXX起效果的核心功能。@Import大家都知道,就是往容器裡面註入一個配置類,但是這個配置類可是有講究的。

這裡我直接上源碼,帶你看看@Import註解功能是如何實現的。

@Import註解的功能是在org.springframework.context.annotation.ConfigurationClassParser類processImports方法處理的。接下來我們就來解讀一下實現的核心部分。

首先判斷@Import註解導入的是配置類有沒有實現ImportSelector介面,實現的話就就調用ImportSelector的selectImports方法,這個方法返回的是一批配置類的全限定名,然後繼續解析這些配置類。

ImportSelector介面的作用其實就是往spring容器中再次註入一批配置類。

如果沒有實現ImportSelector介面,那麼再判斷有沒有實現ImportBeanDefinitionRegistrar,有的話就會調用ImportBeanDefinitionRegistrar的registerBeanDefinitions方法,通過名字也可以判斷出,其實就是往spring容器註入一些BeanDefinition。

ImportBeanDefinitionRegistrar的作用其實很簡單,就是往spring容器註入一些BeanDefinition。如果不是很清楚BeanDefinition是什麼,歡迎查看Spring bean到底是如何創建的?(上)這篇文章,有講解。

如果這兩個介面都沒有實現,那麼就當時一個普通的配置類進行解析。

讀完@Import實現的源碼,我們再來總結回顧@Import的作用。

@Import註解,就是導入一個配置類,但是這個配置類分為不同的情況。如果這個配置類實現了ImportSelector介面,那麼就會調用selectImports方法的實現,獲取一批配置類的全限定名,然後再解析配置類;如果實現了@Import註解導入的配置類實現類ImportBeanDefinitionRegistrar,那麼就會調用registerBeanDefinitions方法的實現,這個方法可以往容器中註入BeanDefinition;最後如果都沒實現,那麼就按照一個普通的配置類來解析。

所以基於這麼一套配置類解析的規則,就可以實現往容器中註入一些bean,通過這些bean來完成某塊功能的實現。

@EnbaleAsync註解的是如何起作用的

懂了@Enbale模塊驅動的基本原理,接下來我們舉個例子,來看看@EnbaleAsync註解是如何實現的。

@EnbaleAsync註解上通過@Import註解導入了AsyncConfigurationSelector類

接下來我們進入這個類

一看源碼,就發現繼承了AdviceModeImportSelector,其實這個類實現了ImportSelector介面,附上源碼

其實這個對於ImportSelector介面的實現就是解析註解的屬性,然後拿到一個AdviceMode,再調用一個模板方法selectImports,這個方法主要子類來實現,所以我們來看看AsyncConfigurationSelector的實現。

這個adviceMode是註解@EnableAaync註解中的屬性mode(),你可以自己翻一下,預設是PROXY,所以這個方法其實就是返回ProxyAsyncConfiguration類的全限定名,其實就是往容器中添加了ProxyAsyncConfiguration配置類。

我們進入這個配置類看一下

其實就是往容器中註入一個AsyncAnnotationBeanPostProcessor,通過名字可以看出這是一個BeanPostProcessor,也就是在bean的生命周期的某個節點來處理@Aysnc註解,如果有不懂BeanPostProcessor的同學可以看看Spring bean到底是如何創建的?(上)和 Spring bean到底是如何創建的?(下)這兩篇文章,裡面有詳細的說明。至於AsyncAnnotationBeanPostProcessor的實現我們就不再繼續深究了,有興趣的同學可以自行點進去看看。

所以說白了,@EnbaleAsync註解的主要作用就是往容器中添加一個可以住了@Async註解的AsyncAnnotationBeanPostProcessor,在bean創建的某個階段起到作用。

看完@EnableAsync註解的實現,你也可以仿照這個註解的實現來自己實現一個@Enable來實現某個特定的功能。

本文到這裡也就結束了。

如果我的文章對你有所幫助,還請幫忙點贊、在看、轉發一下,你的支持會激勵我輸出更高質量的文章,碼字不易,非常感謝!

如果你想聯繫我,歡迎關註我的個人的微信公眾號三友的java日記,公眾號會持續推送優質的技術文章,期待與你一起進步。

 

最近花了一個月的時間,整理了這套併發編程系列的知識點。涵蓋了 volitile、synchronized、CAS、AQS、鎖優化策略、同步組件、數據結構、線程池、Thread、ThreadLocal,幾乎覆蓋了所有的學習和麵試場景,如圖。

 

 

 

文檔獲取方式

鏈接:https://pan.baidu.com/s/129wZe3ywAUsjOqTU037Kmg
提取碼:aps9


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

-Advertisement-
Play Games
更多相關文章
  • 1.字元集/字元編碼是什麼? 字元集或者說字元編碼就是給字元定義了數值編號以及數值編號存儲格式。 嚴格來說字元集和字元編碼是兩個概念: charset 是 character set 的簡寫,即字元集。 encoding 是 charset encoding 的簡寫,即字元集編碼,簡稱編碼。 字元集 ...
  • HashMap源碼 目錄 1.1 包含的屬性 1.2 構造器 1.3 hash方法源碼 1.4 put源碼 1.5 resize源碼 1.6 table 變數為什麼用transient 修飾 1.1 包含的屬性 public class HashMap<K,V> extends AbstractMa ...
  • 前言 最近刷b站,看到一位up主利用python製作了一個校園網自動連接的程式,看完很是心動。想著自己也學過python,準備嘗試一下。前前後後摸索了兩天,這裡分享一下實現過程。 一、前期準備 導入需要的庫 import requests #請求鏈接 import base64 #密碼加密 impo ...
  • 對Java_lambda表達式 Stream流 Option類進行總結和簡要介紹 ...
  • 整體框架 綠色代表介面/抽象類;藍色代表類。 主要由兩大介面組成,一個是「Collection」介面,另一個是「Map」介面。 前言 以前剛開始學習「集合」的時候,由於沒有好好預習,也沒有學好基礎知識,介面,類,這些基礎知識都沒學好,所以學到這裡還是懵懵懂懂的。第一次接觸到「集合」,這兩個字,在我的 ...
  • C++ string 字元串類詳解:深入淺出地介紹了各種【string的使用方法】,其中包含了所有【string常用函數】。 ...
  • 樹 建議閱讀順序(有些沒有嚴格的順序關係): 線段樹 \(\rightarrow\) 輕重鏈剖分(長短鏈剖分) \(\rightarrow\) \(LCA\&LA\) \(\rightarrow\) 全局平衡二叉樹 \(\rightarrow\) 動態樹 數據結構 線段樹 https://www.c ...
  • 一個去京東面試的工作了5年的粉絲來找我說: Mic老師,你說併發編程很重要,果然我今天又掛在一道併發編程的面試題上了。 我問他問題是什麼,他說:”如何中斷一個正在運行中的線程?“。 我說這個問題很多工作2年的人都知道~ 好吧,對於這個問題,來看看普通人和高手的回答。 普通人: 嗯。。。。。。。。。。 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...