中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringBoot2入門自動配置原理源碼分析

發布時間:2022-05-30 10:43:26 來源:億速云 閱讀:160 作者:zzz 欄目:開發技術

這篇文章主要介紹“SpringBoot2入門自動配置原理源碼分析”,在日常操作中,相信很多人在SpringBoot2入門自動配置原理源碼分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”SpringBoot2入門自動配置原理源碼分析”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

    SpringBoot自動配置

    之前為什么會去了解一些底層注解,其實就是為了后續更好的了解 springboot 底層的一些原理,比如自動配置原理。

    一、@SpringBootApplication

    從 MainApplication 中的@SpringBootApplication開始。

    SpringBoot2入門自動配置原理源碼分析

    進入@SpringBootApplication,可以看到這是一個合成注解(紅框中是要關注的)。

    SpringBoot2入門自動配置原理源碼分析

    1. @SpringBootConfiguration

    這個注解干嘛的?

    直接點進去,發現有一個@Configuration注解,那這不就是個配置類嘛。

    SpringBoot2入門自動配置原理源碼分析

    進而也說明了,MainApplication 也是一個配置類。

    2. @ComponentScan

    這個已經很熟悉了,可以指定掃描哪些 Spring 注解。

    只不過這里,加了一些其他的過濾條件,暫時不關注。

    3. @EnableAutoConfiguration

    這個是最重要的注解了,聽名字就不一般,開啟自動配置。

    點進去,發現也是一個合成注解(紅框需要關注)。

    SpringBoot2入門自動配置原理源碼分析

    (1)@AutoConfigurationPackage

    聽名字像是自動配置包?依舊點進去。

    SpringBoot2入門自動配置原理源碼分析

    可以看到原來是導入了一個叫Registrar的組件,繼續點進 Registrar

    SpringBoot2入門自動配置原理源碼分析

    這里是利用Registrar()給容器中導入一系列組件,也就是批量注冊組件

    在這里打個斷點,debug 啟動一下。

    SpringBoot2入門自動配置原理源碼分析

    registerBeanDefinitions()方法中有個傳參:

    metadata,是注解的元信息,可以看到這個注解是被標注在com.pingguo.boot.MainApplication

    而在registerBeanDefinitions()方法體內,new 了一個AutoConfigurationPackages.PackageImports(),里面傳入的是元注解,通過getPackageNames()獲取到包名。

    AutoConfigurationPackages.register(
        registry, (String[])(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames().toArray(new String[0])
    );

    在 idea 中可以單獨執行下片段代碼(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames()

    SpringBoot2入門自動配置原理源碼分析

    選中右擊,再點擊 Evaluate。

    SpringBoot2入門自動配置原理源碼分析

    得到的結果就是com.pingguo.boot。為什么是這個?因為注解標注在MainApplication類,而這個類就屬于com.pingguo.boot

    拿到包名之后,封裝到數組里,也就是上述代碼片段中的toArray(new String[0]),最后注冊進去。

    所以,這里的Registrar()就是把指定的包下的所有組件批量注冊到容器中。

    (2)@Import(AutoConfigurationImportSelector.class)

    上面指定好默認包規則之后,就需要去導入需要的包了,利用的是AutoConfigurationImportSelector,繼續點進去看。

    SpringBoot2入門自動配置原理源碼分析

    這里有個selectImports方法,這個方法決定了要具體導入哪些,返回的是一個數組。

    方法體內,又是調用了getAutoConfigurationEntry()方法來獲取配置入口,進而再通過getConfigurations()方法獲取具體配置,最終轉成數組返回。

    顯然getAutoConfigurationEntry()是個重點。

    往下翻一點,就是getAutoConfigurationEntry()的實現,在這里打個斷點(把上面的斷點取消掉)。

    SpringBoot2入門自動配置原理源碼分析

    debug重新運行一下,往下走到getCandidateConfigurations()

    SpringBoot2入門自動配置原理源碼分析

    這里是獲取所有候選配置,目前可以看到這里是共有 127 個。

    SpringBoot2入門自動配置原理源碼分析

    為什么是這 127 個?其實是在配置文件里寫死了,在 springboot 啟動時候,給容器加載的所有場景的配置類。

    定義的位置是在這:\spring-boot-autoconfigure\2.3.4.RELEASE\spring-boot-autoconfigure-2.3.4.RELEASE.jar!\META-INF\spring.factories

    SpringBoot2入門自動配置原理源碼分析

    雖然這些一股腦的在啟動時候會去加載到容器,但是最終會按需開啟配置。

    SpringBoot2入門自動配置原理源碼分析

    比如點開aop,看到@ConditionalOnClass({Advice.class})這個條件,是當存在Advice類時候才導入組件,但實際上這里并沒有Advice

    這就是基于 springboot 的按條件裝配@Conditional,根據規則最終實現按需裝配。

    二、自動配置示例

    分別用最終未生效、和生效的自動配置來加深理解。

    1. 未生效的自動配置

    比如 cache。

    SpringBoot2入門自動配置原理源碼分析

    可以看到CacheAutoConfiguration上是加了幾個條件裝配的。

    SpringBoot2入門自動配置原理源碼分析

    (1)@ConditionalOnClass({CacheManager.class})

    在 idea 中使用ctrl+N搜索一下CacheManager,發現是存在的,那么這個條件滿足。

    SpringBoot2入門自動配置原理源碼分析

    (2)@ConditionalOnBean({CacheAspectSupport.class})

    這個條件是要求容器中存在CacheAspectSupport這個組件才可以。

    現在來判斷一下是否存在這個組件,在 main 方法里增加測試代碼:

    ... ...
          String[] beanNamesForType = run.getBeanNamesForType(CacheAspectSupport.class);
          System.out.println("==CacheAspectSupport類型組件的數量==" + beanNamesForType.length);
    ... ...

    運行查看輸出。

    SpringBoot2入門自動配置原理源碼分析

    發現數量等于 0,也就是不存在該類型的組件。

    也就是說@ConditionalOnBean({CacheAspectSupport.class})這個條件不滿足,所以整個類CacheAutoConfiguration里的配置都不生效。

    2. 生效的自動配置

    之前寫過 web 的demo,那么 web 相關的配置自然是生效的,找到它。

    SpringBoot2入門自動配置原理源碼分析

    這里有不少后綴是**AutoConfiguration的配置,直接來看DispatcherServletAutoConfiguration

    SpringBoot2入門自動配置原理源碼分析

    @Configuration(proxyBeanMethods = false):表示是一個配置類。

    @ConditionalOnWebApplication(type = Type.SERVLET):條件是否為一個 web 應用,而且是原生 SERVLET 類型的(因為springboot2還有webflux),當前滿足條件。

    @ConditionalOnClass({DispatcherServlet.class}):條件是否導入了DispatcherServlet類,這里也是有的。

    SpringBoot2入門自動配置原理源碼分析

    還有 2 個注解直接沒見過,這里不用太多關注,了解一下:

    @AutoConfigureOrder:這個配置類的配置優先級順序。@AutoConfigureAfter:表示在xx之后才配置這個類,這里就是在配置完ServletWebServerFactoryAutoConfiguration.class后,再配置當前的類。

    所以,類上的幾個條件都是滿足的,就可以進一步到類中了,繼續往下找:

    SpringBoot2入門自動配置原理源碼分析

    看到DispatcherServletConfiguration類上也有條件:

    @Conditional({DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition.class}):

    別看這么長,其實就是上面的一個類

    @ConditionalOnClass({ServletRegistration.class}): 這個也存在。

    SpringBoot2入門自動配置原理源碼分析

    @EnableConfigurationProperties({WebMvcProperties.class}):

    這個很熟悉了,使用前面剛學習完不久,它并不是條件裝配,而是用來綁定外部配置文件的,點進去。

    SpringBoot2入門自動配置原理源碼分析

    可以看到,會與配置文件中前綴是spring.mvc的所有屬性進行綁定。

    另外,還可以自動把組件注冊到容器中去。

    這里可以試一下,在 main 方法里增加輸出:

    String[] beanNamesForType1 = run.getBeanNamesForType(WebMvcProperties.class);
        System.out.println("==WebMvcProperties類型組件的數量==" + beanNamesForType1.length);

    運行一下,果然是有一個:

    SpringBoot2入門自動配置原理源碼分析

    到此,說明DispatcherServletConfiguration這個配置類也是生效的。

    繼續往下就看到方法dispatcherServlet(),而且是加了@Bean注解,就是給容器中注冊DispatcherServlet類型的組件。

    SpringBoot2入門自動配置原理源碼分析

    這里的經過是:

    new 一個DispatcherServlet()對象dispatcherServlet。接著對dispatcherServlet一通 set 設置。最后返回這個對象dispatcherServlet

    在之前學習 springMVC 時候,還要手動去設置關于DispatcherServlet的一堆東西。而在 springboot 里已經在底層設置好了,并且注冊到容器中去了,所以我們能直接使用。

    到此,關于“SpringBoot2入門自動配置原理源碼分析”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    温州市| 宝兴县| 青龙| 永州市| 淄博市| 永城市| 岳阳市| 吉林市| 榆树市| 秦安县| 湖南省| 苏尼特右旗| 饶河县| 诏安县| 伊吾县| 南丰县| 新和县| 辽中县| 东莞市| 灵台县| 彭水| 宁安市| 孟州市| 会泽县| 旬阳县| 饶河县| 峨边| 巫山县| 泸溪县| 抚州市| 安丘市| 胶州市| 高平市| 旬邑县| 石阡县| 黄浦区| 合阳县| 凉城县| 鹤峰县| 平昌县| 横山县|