【JavaWeb】Springboot的四個特性:自動裝配

一、前言

二、Springboot四個特性

springboot和微服務的關係是什麼?
回答:所有的微服務組件,都是集成到springboot上面,spring cloud也是一樣,在使用springcloud的時候,它應該和springboot在版本上兼容。

1、第一特性,EnableAutoConfiguration ,譯爲自動裝配

2、第二特性,Starter啓動依賴,依賴於自動裝配的請求。
3、第三特性,Actuator監控,提供一些endpoint,這些endpoint可以基於http jmx 等形式去進行訪問health信息,metrics信息。

4、第四特性,Spring Boot CLI它是爲springcloud提供的springboot命令行操作的功能,它通過groovy腳本快速構建springboot的應用,用得很少,一般還是基於idea應用構建springboot應用,略過。

小結:自動裝配和啓動依賴是不同的,兩者關係是啓動依賴依賴於自動裝配,監控提供一些訪問形式。

三、Springboot自動裝配

3.1 Springboot牛刀小試:整合redis,引入自動裝配

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

問題:能夠實現@Autowired依賴注入的前提是是IOC中存在這個bean的實例,那麼是誰裝載了這個bean實例?

回答:spring中裝載bean實例包括三種方式:xml文件 configuration類 enable註解,現在這三種方式我們都沒做,但是爲什麼springboot可以實現bean裝配,這就是springboot的自動裝配,完成bean的自動裝載,只要寫出來@Autowired,自動裝配的原理是怎麼實現的。

3.2 自動裝配的思考

3.2.1 自動裝配的思考

在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述

springboot爲什麼能夠完成自動裝配?
一句話總結,在pom.xml中引入的依賴(即jar包),都被約定好帶有統一的格式,都有XxxConfiguration類,使用時springboot直接對其掃描,就完成了裝配,但是這是對開發程序員不可見的,所以被稱爲自動裝配。每個第三方的starter裏面都有一個配置類XxxConfiguration類,這是一種約定。

在這裏插入圖片描述

Springboot自動裝載問題1:Spring引擎怎麼知道第三方組件starter裏面具體配置類在哪裏?

Springboot自動裝載問題2:如何實現批量掃描配置類XxxConfiguration redis mybatis dubble?

3.2.2 從靜態裝配bean實例到動態裝配bean實例

spring靜態裝配三種方式:xml文件 Configuration配置類 @Enable模塊裝配
spring動態裝配兩種方式:ImportSelector接口 Registator接口

每一個第三方starter裏面都有一個配置類XxxConfiguration,Springboot中使用多個第三方組件,如何批量掃描多個配置類XxxConfiguration

答案:批量bean加載機制。spring存在兩種動態bean裝載機制,一種是ImportSelector接口,一種是Registator接口,都是接口,本文介紹ImportSelector接口。

動態裝載:根據運行時上下文的具體運行條件來狀態來裝載配置類XxxConfiguration,不同於@Conditional。

3.3 自動裝配的模擬

這部分給出一個項目,模擬springboot自動裝配,項目結構如下:

在這裏插入圖片描述

3.3.1 兩個bean和兩個配置類

給出一個mybatis bean類、mybatis 模擬配置類、redis bean類、redis 模擬配置類

在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述

3.3.2 MyImportSelector類

模擬ImportSelector實現類,實現ImportSelector接口,返回配置類

在這裏插入圖片描述

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        // 在這裏去加載所有的配置類
        // 通過某種機制去完成指定路徑的配置類的掃描就行?
        // spring只需要知道 package.class.classname 就行了。
        return new String[]{MybatisConfiguration.class.getName(), RedisConfiguration.class.getName()};
    }
}

3.3.3 @MyEnableConfiguration註解

如何讓SpringbootApplication知道MyImportSelector返回的配置類?只需要聲明一個註解就可以完成。

定義一個註解,@Import(ImportSelector接口實現類.class)
在這裏插入圖片描述
SpringApplicationdemoApplication類中使用這個註解
在這裏插入圖片描述

在這裏插入圖片描述

3.3.4 詳細運行流程解釋

本項目中,其實SpringbootApplication不要使用@MyEnableConfiguration也可以,因爲SpringbootdemopageApplication所在包爲package com.example.demo;但是,兩個bean所在包爲package com.example.demo.mybatis 和 package com.example.demo.redis,這樣,啓動SpringbootdemopageApplication,會掃描所在包及其子包,就掃描到了兩個bean。

如果SpringbootdemopageApplication在com.example.demo.springbootdemo,必須配置@MyEnableConfiguration註解,啓動的時候,掃描@MyEnableConfiguration註解,然後知道它@Import(MyImportSelector.class),在MyImportSelector.class中,spring才知道兩個配置類的路徑,纔有了下面的裝載bean並打印出來。

在這裏插入圖片描述

3.3.5 附加:既可以是配置類,也可以直接是bean類

在這裏插入圖片描述

貌似MyImportSelector 返回值中直接放bean類會出現重複裝配的情況,總之,最好放配置類。

小結:這個實例告訴我們,springboot底層使用ImportSelector接口+註解動態裝載,無論第三方組件(項目中com.example.demo.mybatis 和 com.example.demo.redis模擬第三方組件,每一個組件都包括配置類和實體bean)的配置在哪裏,都可以用ImportSelector接口找到,並用註解告訴springboot,解決了第一個問題。對於n個配置類(項目中mybatis和redis模擬兩個配置類),可以批量配置,不是問題。

注意1:使用@ComponentScan或base-package不可以,它是靜態裝配,需要把掃描的路徑寫死,但是在使用一個第三方組件的時候,你是不知道它的bean或配置類在哪裏的,這就是靜態裝配的侷限,只能用動態裝配。
注意2:使用@Contional 也不僅,僅僅只是一個給出一個判斷,裝配還是不裝配,當然下文我們的有條件配置。

3.4 從模擬到實際,解析自動裝配的底層原理

3.4.1 從模擬到實際,springboot底層實現動態裝配

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

**可以看到,springboot的動態裝載的底層實現的@SpringBootApplication註解和我們的模擬的時候的自定義註解@MyEnableConfiguration底層是一樣的,都是集成ImportSelector接口實現其selectImports返回配置類數組。**難怪剛剛開始的redisTemplate可以自動裝配。

在這裏插入圖片描述

3.4.2 從模擬到實際,redis配置類

在這裏插入圖片描述

3.4.3 Springboot自動裝載的核心源碼

@Autowird
private RedisTemplate redisTemplate;   // 自動裝載

第一,AutoConfigurationImportSelector 自動配置ImportSelector :getAutoConfigurationEntry 獲得自動配置/自動裝載實體

在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

第二,SpringFactoriesLoader 表示 :spring.factories 加載

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

3.5 springboot自動裝配小結

開發程序員使用的時候,只要直接使用

@Autowired
private RedisTemplate<string,string> redisTemplate;  // 自動配置好了的,直接用就好

問題:剛纔的項目只是在自己的項目中模擬,那麼具體實踐中,spring引擎怎麼知道具體starter配置類在哪裏?

回答:第一,所有starter遵循統一的約定,所有的starter組件,都需要一個META-INF/spring.factories文件,如下:

在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述

第二,springboot直接掃描配置文件(org.redis.RedisConfiguration org.mybatis.MybatisConfiguration)就好了,如下圖:

在這裏插入圖片描述

在這裏插入圖片描述
第三,自動裝載就完成了。

3.6 SPI 設計思想

3.6.1 什麼是SPI?

SPI 全稱 Service provider interface ,服務提供接口,這裏以各個不同的數據庫驅動爲例,如圖:

在這裏插入圖片描述

SPI 就是我們提供接口,接口的具體實現由第三方來做(這裏,不同的數據庫驅動是不同的,由數據庫廠商來完成),Java程序只要導入不同的jar包就可以執行,這就是SPI的擴展,就是服務提供接口的擴展。

爲什麼說spring.factories也是SPI,spring.factories 是基於key-value鍵值對的,其中key就是同一個Configuration,value由第三方具體實現;因爲每一個starter組件的jar包都有一個Configuration註解,提供一個與springboot溝通接口,其內部具體實現由第三方來做(redis mybatis dubbo),springboot只要導入不同的jar包(redis依賴 mybatis依賴 dubbo依賴)就好。

一句話總結DPI:
DPI 本身包含默認實現,但是也提供擴展點,需要的話可以替換,提高伸縮性和靈活性。

3.6.2 DPI設計思想的demo

DPI設計得以實現需要滿足以下條件:

1、需要在classpath目錄下創建一個META-INF/services

2、在該目錄下創建一個擴展點的全路徑名
2.1 文件中填充這個擴展點的實現
2.2 文件編碼格式UTF-8

3、ServiceLoader去進行加載

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

注意事項:META-INF和services目錄必須分開創建

在這裏插入圖片描述

maven quickstart 項目,maven clean maven install 之後變成jar包;
maven webapp 項目,maven clean maven install 之後變爲war包。

四、Springboot自動裝配進一步深入

starter組件與自動裝配緊密相連,因爲所有的第三方的starter組件都是遵循自動裝配的約定,提供spring.factories文件,提供配置類給springboot掃描完成自動裝配。

4.1 Starter組件的原理:官方包依賴的條件觸發

4.1.1 條件註解引入

在這裏插入圖片描述

在這裏插入圖片描述

4.1.2 官方依賴包中不存在spring.factories

在這裏插入圖片描述

對於官方的springboot starter,不存在spring.factories,那麼爲什麼不存在spring.factories,它又是如何加載的?
原來,starter包包括兩種,
官方包 spring-boot-starter-xxx 不存在 spring.factories 如spring-boot-starter-data-redis spring-boot-starter-thymeleaf
第三方包 xxx-spring-boot-starter 一定存在spring.factories

以Redis爲例,其配置類RedisAutoConfiguration不存在 spring-boot-starter-data-redis 裏面 ,而是不存在spring-boot-autoconfigure包,

在這裏插入圖片描述

既然如何,springboot又是如何找到配置類RedisAutoConfiguration的呢?
答案是條件註解。

4.1.3 條件註解確保配置類完成配置

在這裏插入圖片描述

在這裏插入圖片描述

小結,官方包的依賴就是條件觸發。

附:spring.factories中記錄官方包的配置類定位

在這裏插入圖片描述

在這裏插入圖片描述
這裏面這些都只需要導入依賴就好,只有第三方包才需要自己寫spring.factories。

4.2 demo spring.factories自定義組件的配置類的裝載

新建maven quickstart項目:autoconfiguredemo

想·

在這裏插入圖片描述

spring.factories文件中指定配置類路徑
在這裏插入圖片描述

maven clean maven install 成爲一個jar包,給springboot工程去使用

新建一個maven quickstart 工程 springbootcore2,導入依賴

在這裏插入圖片描述

在這裏插入圖片描述

4.3 demo @ConditionalOnClass等註解實現條件配置

現在在第一個工程Configuration配置類上面使用條件註解,表示要滿足某一個條件才裝載,就使用 @ConditionalOnClass({RedisOperations.class}) 就好了。

先導入依賴

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

4.4 demo spring-autoconfigure-metadata.properties 實現條件配置

在springboot中存在一個spring-autoconfigure-metadata.properties文件,它也是一種配置文件。
在這裏插入圖片描述

這種配置文件只是,使用者需要按要求這樣配置,實際上我們自己的工程也可以實現這種配置文件並打成jar包的。

源工程

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

4.5 兩種配置方式一起使用

並不是所有的條件配置都是寫在類上面的註解上面的,也可以通過spring-autoconfigure-metadata.properties配置文件去寫,且看mybatis

這裏是mybatis的條件配置文件 spring-autoconfigure-metadata.properties

在這裏插入圖片描述

這裏是mybatis的條件註解
在這裏插入圖片描述

五、小結

本文介紹Springboot自動裝配的特性,從使用redis引入了自動裝配,然後理解自動裝配、模擬實現、閱讀springboot源碼,最後引入條件觸發和demo實現。

天天打碼,天天進步!!!

自動裝配模擬工程代碼:https://download.csdn.net/download/qq_36963950/12555256

SPI設計思想工程代碼:https://download.csdn.net/download/qq_36963950/12555258

自動裝配+條件註解+條件配置文件工程代碼:https://download.csdn.net/download/qq_36963950/12555260

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章