springboot自動裝配原理探究

来源:https://www.cnblogs.com/radish40/archive/2022/06/04/16342809.html
-Advertisement-
Play Games

springboot自動裝配原理探究 結論: SpringBoot啟動會載入大量的自動配置類 我們看我們需要的功能有沒有在SpringBoot預設寫好的自動配置類當中; 我們再來看這個自動配置類中到底配置了哪些組件;(只要我們要用的組件存在在其中,我們就不需要再手動配置了) 給容器中自動配置類添加組 ...


springboot自動裝配原理探究

結論:

  1. SpringBoot啟動會載入大量的自動配置類
  2. 我們看我們需要的功能有沒有在SpringBoot預設寫好的自動配置類當中;
  3. 我們再來看這個自動配置類中到底配置了哪些組件;(只要我們要用的組件存在在其中,我們就不需要再手動配置了)
  4. 給容器中自動配置類添加組件的時候,會從properties類中獲取某些屬性。我們只需要在配置文件中指定這些屬性的值即可;

對於配置類的讀取:

  1. 根據當前不同的條件判斷,決定這個配置類是否生效!
  2. 一但這個配置類生效;這個配置類就會給容器中添加各種組件;
  3. 這些組件的屬性是從對應的properties類中獲取的,這些類裡面的每一個屬性又是和配置文件綁定的;
  4. 所有在配置文件中能配置的屬性都是在xxxxProperties類中封裝著;
  5. 配置文件能配置什麼就可以參照某個功能對應的這個屬性類
  1. 首先創建一個springboot項目,打開主啟動類

存在如下註解:

  • @SpringBootApplication

    放在項目的一個啟動類上,用來把啟動類註入到容器中,用來定義容器掃描的範圍,用來載入classpath環境中一些bean。

  1. 點進@SpringBootApplication

可以看到包含如下註解:

  • @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    

    四大元註解。

  • @SpringBootConfiguration

    標識一個springboot配置類

  • @EnableAutoConfiguration

    啟動自動裝配

  • @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

    開啟組件掃描

  1. 先點進@ComponentScan中看看掃描了什麼組件

在這個註解下我們找到了這樣一個屬性:

/**
 * Controls the class files eligible for component detection.
 * <p>Consider use of {@link #includeFilters} and {@link #excludeFilters}
 * for a more flexible approach.
 */
String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;

找到這個屬性值:

public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {

	static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
    
}

可以看到幫我們導入了所有當前啟動類所在路徑下的任意類文件

  1. 接著點擊@EnableAutoConfiguration,讓我們去看看自動裝配都做了什麼

可以看到存在如下註解:

  • @AutoConfigurationPackage

    自動配置包

  • @Import(AutoConfigurationImportSelector.class)

    spring的底層註解,引入一個資源

  1. 點擊@AutoConfigurationPackage

我們看到自動配置包引入了一個類資源,點進去看看

該類存儲來自導入配置的包

  1. 點擊@Import(AutoConfigurationImportSelector.class),我們去看看這個註解引入的資源內容

這是一個自動配置導入選擇器

我們找到其中的個別方法

  • 獲取自動配置實體

  • 獲得候選配置

在候選配置中,我們註意到它調用了一個SpringFactoriesLoader.loadFactoryNames()方法:

List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				getBeanClassLoader());
  1. 讓我們去看看SpringFactoriesLoader這個類

這是一個用於框架內部使用的通用工廠載入機制。

這是剛剛看到的loadFactoryNames()方法:

這個類中還存在這樣一個方法:

private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
   Map<String, List<String>> result = cache.get(classLoader);
   if (result != null) {
      return result;
   }

   result = new HashMap<>();
   try {
      Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
      while (urls.hasMoreElements()) {
         URL url = urls.nextElement();
         UrlResource resource = new UrlResource(url);
         Properties properties = PropertiesLoaderUtils.loadProperties(resource);
         for (Map.Entry<?, ?> entry : properties.entrySet()) {
            String factoryTypeName = ((String) entry.getKey()).trim();
            String[] factoryImplementationNames =
                  StringUtils.commaDelimitedListToStringArray((String) entry.getValue());
            for (String factoryImplementationName : factoryImplementationNames) {
               result.computeIfAbsent(factoryTypeName, key -> new ArrayList<>())
                     .add(factoryImplementationName.trim());
            }
         }
      }

      // Replace all lists with unmodifiable lists containing unique elements
      result.replaceAll((factoryType, implementations) -> implementations.stream().distinct()
            .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)));
      cache.put(classLoader, result);
   }
   catch (IOException ex) {
      throw new IllegalArgumentException("Unable to load factories from location [" +
            FACTORIES_RESOURCE_LOCATION + "]", ex);
   }
   return result;
}

在這個方法中我們可以看到,它載入了一個FACTORIES_RESOURCE_LOCATION資源,並將從資源中拿到的東西封裝成一個個的Properties供接下來使用

/**
 * The location to look for factories.
 * <p>Can be present in multiple JAR files.
 */
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
  1. 找到這個資源META-INF/spring.factories

可以看到這個文件的內容就是我們用的一個又一個的配置

  1. 找個我們熟悉的,例如HttpEncodingAutoConfiguration點進去看看

看到瞭如下的註解:

  • @Configuration(proxyBeanMethods = false)

    配置類標識

  • @EnableConfigurationProperties(ServerProperties.class)

    啟用配置屬性

  • @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)

    Spring底層@Conditional註解
    根據不同的條件判斷,如果滿足指定的條件,整個配置類裡面的配置就會生效;
    這裡的意思就是判斷當前應用是否是web應用,如果是,當前配置類生效

  • @ConditionalOnClass(CharacterEncodingFilter.class)

    判斷當前項目有沒有這個類CharacterEncodingFilter;SpringMVC中進行亂碼解決的過濾器;

  • @ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)

    判斷配置文件中是否存在某個配置:server.servlet.encoding.enabled;
    如果不存在,判斷也是成立的
    即使我們配置文件中不配置server.servlet.encoding.enabled=true,也是預設生效的;

可以看到它已經綁定了一個配置文件

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
  //...
}

從此可以看到配置文件里寫的東西都在這個屬性類中封裝著,也就是說這個類里有的我們都可以在配置文件中配置

總結 :

  1. 根據當前不同的條件判斷,決定這個配置類是否生效!

  2. 一但這個配置類生效;這個配置類就會給容器中添加各種組件;

  3. 這些組件的屬性是從對應的properties類中獲取的,這些類裡面的每一個屬性又是和配置文件綁定的;

  4. 所有在配置文件中能配置的屬性都是在xxxxProperties類中封裝著;

  5. 配置文件能配置什麼就可以參照某個功能對應的這個屬性類

這就是自動裝配的原理!

xxxxAutoConfigurartion:自動配置類;給容器中添加組件
xxxxProperties:封裝配置文件中相關屬性;


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

-Advertisement-
Play Games
更多相關文章
  • 閑來無事,嘗試一下HTTPS。 正好華為雲有活動,功能變數名稱10塊錢一年,證書免費。 參考:https://www.bbsmax.com/A/B0zqr3wnJv/ 功能變數名稱綁定&申請證書 照著說明做就行。 安裝證書 這就是這篇博客的重點了。 安裝nginx的ssl模塊 如果還沒有安裝nginx的話,可以參考 ...
  • top top命令是Linux下常用的性能分析工具,能夠實時顯示系統中各個進程的資源占用狀況,類似於Windows的任務管理器。top顯示系統當前的進程和其他狀況,是一個動態顯示過程,可以自動或者通過用戶按鍵來不斷刷新當前狀態。如果在前臺執行該命令,它將獨占前臺,直到用戶終止該程式為止.。比較準確的 ...
  • 寫在前面 某音作為風靡中外的一款音樂創意短視頻社交軟體,其成功性不言而喻,一直聽說其強大的“威力”,但卻從沒深入研究過,作為人民的先鋒隊,這怎麼行,毅然決然的我,在上周五註冊了一個賬號,但沒想到的是等待我的確是一條不歸路~(以下內容純屬個人經歷與個人看法,沒有任何代表性,圖一樂呵兒) 一個視頻在發出 ...
  • 一、游標概念 • 在 PL/SQL 塊執行 SELECT/INSERT/UPDATE/DELETE 語句時,Oracle 會在記憶體中為其分配上下文區,而游標是指向該區域的指針。 • 游標為應用程式提供了一種對具有多行數據查詢結果集中的每一行單獨處理的方案,是設計互動式應用程式的編程介面。 二、游標優 ...
  • 一、引言 • PL/SQL 程式可通過條件或迴圈結構來控制命令執行的流程。 • PL/SQL 提供了豐富的流程式控制制語句,與 Java 一樣也有三種控制結構: • 順序結構 • 選擇結構 • 迴圈結構 二、選擇結構 2.1、IF-THEN 1)IF-THEN 該結構先判斷一個條件是否為 TRUE,條件 ...
  • GPU 渲染機制:CPU計算好顯示內容提交到GPU,GPU渲染完成後將渲染結果放入幀緩衝區frame buffer,隨後視頻控制器會按照VSync信號逐行讀取幀緩衝區的數據,經過可能的數模轉換傳遞給顯示器顯示。 GPU 屏幕渲染有以下兩種方式: ● 1)On-Screen Rendering,意為當 ...
  • 非常感謝小趙同學給我反饋的這個 Bug
  • 前言 眾所周知,spring對於java程式員來說是一個及其重要的後端框架,幾乎所有的公司都會使用的框架,而且深受廣大面試官的青睞。所以本文就以常見的一個面試題"spring bean的生命周期"為切入點,從源碼的角度帶領大家來看一看 spring bean到底是如何創建的 。spring bean ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...