SpringBoot自動裝配初步淺理解

来源:https://www.cnblogs.com/csrecord/archive/2022/07/01/16435628.html
-Advertisement-
Play Games

SpringBoot自動裝配原理 Created time: May 15, 2022 6:36 PM Done: Doing Last edited time: May 25, 2022 6:13 PM Tags: Spring, 後端, 總結 0 關於自動配置 pom.xml spring-bo ...


SpringBoot自動裝配原理

Created time: May 15, 2022 6:36 PM
Done: Doing
Last edited time: May 25, 2022 6:13 PM
Tags: Spring, 後端, 總結

0 關於自動配置

pom.xml

  • spring-boot-dependencies:核心依賴在父工程中
  • 在寫或者引入一些springboot依賴時,不需要指定版本,因為有這些版本倉庫。

啟動器

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • 啟動器,SpringBoot的啟動場景
  • spring-boot-starter-web 自動導入web環境所有的依賴
  • springboot會將所有的功能場景變成一個一個啟動器

主程式

//標註這個類是一個springboot的應用
@SpringBootApplication
public class Springboot01HelloworldApplication {
    public static void main(String[] args) {
        SpringApplication.run(Springboot01HelloworldApplication.class, args);
    }
}

1 SpringBoot四大核心

  • 四大核心
    • EnableAutoConfiguration自動裝配
    • Starter組件,開箱即用
    • Actutor監控
    • SpringBoot Cli為SpringCloud提供SpringBoot命令行功能

1.1 註解

在瞭解Spring註解之前先瞭解一些相關註解的知識。

//標註這個類是一個springboot的應用
@SpringBootApplication
//SpringBoot的配置
@SpringBootConfiguration
  @Configuration //Spring配置類
  @Component//本質還是一個Spring組件
//自動配置
@EnableAutoConfiguration
  @AutoConfigurationPackage//自動配置包
  @Import(AutoConfigurationPackages.Registrar.class)//導入選擇器包註冊
  @Import(AutoConfigurationImportSelector.class)//自動配置導入選擇(自動導入包的核心)
  //獲取所有的配置
  List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
//getCandidateConfigurations獲取所有的候選配置**
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(**getSpringFactoriesLoaderFactoryClass**(),
	getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
	+ "are using a custom packaging, make sure that file is correct.");
	return configurations;
	}
	//EnableAutoConfiguration註解被SpringBootApplication繼承
	protected Class<?> getSpringFactoriesLoaderFactoryClass() {
	  return EnableAutoConfiguration.class;
	}

META-INF/spring.factories自動配置的核心文件

//所有的資源載入到類中
Properties properties = PropertiesLoaderUtils.loadProperties(resource);

結論

SpringBoot所有自動配置都是在啟動的時候掃描並載入:spring.factories所有的自動配置類都在這裡面,但不一定生效,要判斷條件是否成立,只要導入對應的start,就有對應的啟動器了,有了啟動器,自動裝配就會生效,然後就配置成功。

2 Enable註解作用

EnableAutoConfiguration 自動裝配相關的Eable註解.

開啟相關支持,如

  • EnableScheduling ,開啟計劃任務支持
  • EnableAutoConfiguration ,開啟自動裝配支持

EnableAutoConfiguration.java中涉及到Enable開頭的註解都會有一個@Import的註解

3 SpringBoot中的自動裝配原理

自動裝配作為Starter的基礎,也是SpringBoot的核心

SpringBoot的自動裝配是基於EnableAutoConfiguration 實現的,先瞭解一下傳統意義的自動裝配方式。

首先需要瞭解一些前置關於註解的知識

3.1 Configuration註解

Spring3以後,支持兩種配置bean的方式,一種xml文件方式和JavaConfig。

JavaConfig方式

Configuration 註解是JavaConfig形式基於Spring IOC容器配置類使用的一種註解。在啟動類裡邊標註@Configuration 也表示它是一個IOC容器的配置類。

public class DemoClass {

    public void say(){
        System.out.println("sya hello ... ");
    }
}
@Configuration
@Import(UserClass.class)
public class DemoConfiguration {

    @Bean
    public DemoClass getDemoClass(){
        return new DemoClass();
    }
}
public class DemoConfigurationMain {

    public static void main(String[] args) {
        ApplicationContext ac = new AnnotationConfigApplicationContext(DemoConfiguration.class);
        DemoClass bean = ac.getBean(DemoClass.class);
        bean.say();
    }
}

3.2 Configuration本質

Configuration註解本質就是一個Component註解,會被AnnotationConfigApplicationContext 載入,而AnnotationConfigApplicationContextApplicationContext 的具體實現,會根據配置註解啟動應用上下文。所以在Main中通過AnnotationConfigApplicationContext 載入JavaConfig後,可以得到IOC容器中Bean的實例。

@Configuration  //也會被Spring容器托管,註冊到容器中,因為本身就是一個@Component
@ComponentScan("com.kuang.pojo")
@Import(MyConfig2.class)
public class MyConfig {

    //註冊一個Bean相當於之前寫的一個Bean標簽
    //這個方法的名字就相當於Bean標簽中的id屬性
    //這個方法的返回值,就相當於Bean標簽中的class屬性
    @Bean
    public User getUser(){
        return new User();  //返回要註入到Bean的對象
    }
}
public class MyTest {
    public static void main(String[] args) {
        //如果完全使用了配置類方式去做,只能通過AnnotationConfigApplicationContext來獲取容器,通過配置類的class對象載入
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
        User getUser = (User) context.getBean("getUser");
        System.out.println(getUser.getName());
    }
}
@Component
public class User {
    private String name;

    public String getName() {
        return name;
    }

    @Value("xxx")
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

3.3 ComponentScan註解

相當於xml配置文件中的context:component-scan ,主要作用是掃描指定路徑下標識了需要裝配的類,自動裝配到IOC容器中

@Configuration  //也會被Spring容器托管,註冊到容器中,因為本身就是一個@Component
@ComponentScan("com.kuang.pojo")
@Import(MyConfig2.class)
public class MyConfig {

    //註冊一個Bean相當於之前寫的一個Bean標簽
    //這個方法的名字就相當於Bean標簽中的id屬性
    //這個方法的返回值,就相當於Bean標簽中的class屬性
    @Bean
    public User getUser(){
        return new User();  //返回要註入到Bean的對象
    }
}

3.4 Import註解

等同於xml形式下的<import resource/> 註解,將多個分開的容器合併在一個容器中。

方式一:@Import,直接@Import(MyConfig2.class)

方式二:ImportSelector,動態載入實現ImportSelector介面

方式三:ImportBeanDefinitionRegistrar方式,實現ImportBeanDefinitionRegistrar 介面

3.5 深入EnableAutoConfiguration原理

EnableAutoConfiguration通過@Import(AutoConfigurationImportSelector.class) 導入第三方的提供的Bean配置類AutoConfigurationImportSelector

public String[] selectImports(AnnotationMetadata annotationMetadata) {
    if (!this.isEnabled(annotationMetadata)) {
        return NO_IMPORTS;
    } else {
        try {
// 載入META-INF/spring-autoconfigure-metadata.properties 下的元數據信息

            AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
// 獲取候選載入的配置信息 META-INF/spring.factories
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
// 去掉重覆的配置信息
            configurations = this.removeDuplicates(configurations);
// 排序
            configurations = this.sort(configurations, autoConfigurationMetadata);
            // 獲取 註解中配置的 exclusion 信息
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
// 檢查
            this.checkExcludedClasses(configurations, exclusions);
// 移除需要排除的信息
            configurations.removeAll(exclusions);
// 過濾,檢查候選配置類上的註解@ConditionalOnClass,如果要求的類不存在,則這個候選類會被過濾不被載入
            configurations = this.filter(configurations, autoConfigurationMetadata);
// 廣播事件
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            // 返回要被載入的類數組
return (String[])configurations.toArray(new String[configurations.size()]);
        } catch (IOException var6) {
            throw new IllegalStateException(var6);
        }
    }
}

EnableAutoConfiguration 會幫助SpringBoot應用將所有符合@Configuration 配置都載入到當前SpringBoot創建的IOC容器,這裡面藉助了Spring框架提供的一個工具類SpringFactoriesLoader的支持。以及用到了Spring提供的條件註解@Conditional,選擇性的針對需要載入的bean進行條件過濾。

3.6 關於條件過濾

分析AutoConfigurationImportSelector的源碼時,會先掃描spring-autoconfiguration-metadata.properties文件,最後在掃描spring.factories對應的類時,會結合前面的元數據進行過濾,為什麼要過濾呢? 原因是很多的@Configuration其實是依托於其他的框架來載入的,如果當前的classpath環境下沒有相關聯的依賴,則意味著這些類沒必要進行載入,所以,通過這種條件過濾可以有效的減少@configuration類的數量從而降低SpringBoot的啟動時間。

4 總結

SpringBoot自動裝配實現是從classpath中搜尋spring.factory自動裝配的核心文件,將包下對應的org.springframework.boot.autoconfigure的配置項通過反射實例化為對應標註的@Configuration的JavaConfig形式的IOC容器配置類,將然後彙總為實例載入至IOC容器中。

備註:思路還是不太清晰,後續還需再整理一遍深入理解。


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

-Advertisement-
Play Games
更多相關文章
  • bootstrap-select,selectpicker 用法詳細:通過官方文檔翻譯 用過selectpicker的都說好~但是網上中文的教程又找不到比較完整的用法,於是去官網看了下 順便弄過來翻譯一下: 選項可以通過數據屬性或JavaScript傳遞。對於數據屬性,附加選項名稱data-,如 d ...
  • Fundebug 前端異常監控服務 Fundebug提供專業的前端異常監控服務,我們的插件可以提供全方位的異常監控,可以幫助開發者第一時間定位各種前端異常,包括但不限於 JavaScript 執行錯誤以及 HTTP 請求錯誤。 並且,Fundebug 支持 Source Map 還原,記錄用戶行為以 ...
  • 前段時間研究了下基於`Prometheus`構建監控系統相關的概念,並以此為基準設計了一個企業級通用的監控告警平臺的方案。這裡分享一下架構的分析過程以及問題的解決思路。 ...
  • 本篇文章中,將描述如何使用go創建CA,並使用CA簽署證書。在使用openssl創建證書時,遵循的步驟是 創建秘鑰 > 創建CA > 生成要頒發證書的秘鑰 > 使用CA簽發證書。這種步驟,那麼我們現在就來嘗試下。 創建證書的頒發機構 首先,會從將從創建 CA 開始。CA 會被用來簽署其他證書 // ...
  • 本篇代碼提供者: 青燈教育-自游老師 [環境使用]: Python 3.8 Pycharm [模塊使用]: requests >>> pip install requests re json csv 如果安裝python第三方模塊: win + R 輸入 cmd 點擊確定, 輸入安裝命令 pip i ...
  • Java基礎之 數據類型 註釋、標識符、關鍵字 數據類型 類型轉換 變數、常量 運算符 包機制、JavaDoc 數據類型 強類型語言 要求變數的使用要嚴格符合會定,所有變數都必須先定義後才能使用 弱類型語言 變數的使用沒有那麼嚴格 什麼是位元組 位(bit):是電腦 內部數據 儲存的最小單位,110 ...
  • 今天看到一篇博客介紹使用 Lambda 表達式遞歸計算 n!。使用了 C++14 的 generic lambda,給 Lambda 表達式加了一個模板參數,在函數調用的時候將 Lambda 表達式作為參數傳遞給下一層函數。這種方法每次調用函數的時候都要比常規的函數多傳一個參數。我想起兩年前也用 L ...
  • 前言 有時候我們些代碼是總發此疑惑? 為什麼別人採集 xx 網站的時候能成功,而我卻總是不返回給數據 出現這種原因時往往是我們沒有給夠偽裝, 被識別了出來~ 就像人,你出門肯定是要穿衣服的對不,如果你不穿! 走在外面,肯定是最顯眼的一個,不抓你抓誰 還有一種就是明明我之前運行成功了,為什麼我現在再次 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...