<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring Boot 面試殺手锏:自動(dòng)配置原理

          共 3945字,需瀏覽 8分鐘

           ·

          2021-11-09 19:33

          不論在工作中,亦或是求職面試,Spring Boot已經(jīng)成為我們必知必會(huì)的技能項(xiàng)。除了某些老舊的政府項(xiàng)目或金融項(xiàng)目持有觀望態(tài)度外,如今的各行各業(yè)都在飛速的擁抱這個(gè)已經(jīng)不是很新的Spring啟動(dòng)框架。

          當(dāng)然,作為Spring Boot的精髓,自動(dòng)配置原理的工作過(guò)程往往只有在“面試”的時(shí)候才能用得上,但是如果在工作中你能夠深入的理解Spring Boot的自動(dòng)配置原理,將無(wú)往不利。
          Spring Boot的出現(xiàn),得益于“習(xí)慣優(yōu)于配置”的理念,沒(méi)有繁瑣的配置、難以集成的內(nèi)容(大多數(shù)流行第三方技術(shù)都被集成),這是基于Spring 4.x提供的按條件配置Bean的能力。
          初識(shí)Spring Boot時(shí)我們就知道,Spring Boot有一個(gè)全局配置文件:application.properties或application.yml。
          我們的各種屬性都可以在這個(gè)文件中進(jìn)行配置,最常配置的比如:server.port、logging.level.* 等等,然而我們實(shí)際用到的往往只是很少的一部分,那么這些屬性是否有據(jù)可依呢?答案當(dāng)然是肯定的,這些屬性都可以在官方文檔中查找到:
          https://docs.spring.io/spring-boot/docs/2.1.0.RELEASE/reference/htmlsingle/#common-application-properties

          (所以,話又說(shuō)回來(lái),找資料還得是官方文檔,百度出來(lái)一大堆,還是稍顯業(yè)余了一些)
          除了官方文檔為我們提供了大量的屬性解釋,我們也可以使用IDE的相關(guān)提示功能,比如IDEA的自動(dòng)提示,和Eclipse的YEdit插件,都可以很好的對(duì)你需要配置的屬性進(jìn)行提示,下圖是使用Eclipse的YEdit插件的效果,Eclipse的版本是:STS 4。

           以上,是Spring Boot的配置文件的大致使用方法,其實(shí)都是些題外話。
          那么問(wèn)題來(lái)了:這些配置是如何在Spring Boot項(xiàng)目中生效的呢?那么接下來(lái),就需要聚焦本篇博客的主題:自動(dòng)配置工作原理或者叫實(shí)現(xiàn)方式。
          Spring Boot關(guān)于自動(dòng)配置的源碼在spring-boot-autoconfigure-x.x.x.x.jar中:

          當(dāng)然,自動(dòng)配置原理的相關(guān)描述,官方文檔貌似是沒(méi)有提及。不過(guò)我們不難猜出,Spring Boot的啟動(dòng)類上有一個(gè)@SpringBootApplication注解,這個(gè)注解是Spring Boot項(xiàng)目必不可少的注解。那么自動(dòng)配置原理一定和這個(gè)注解有著千絲萬(wàn)縷的聯(lián)系!
          @EnableAutoConfiguration

           @SpringBootApplication是一個(gè)復(fù)合注解或派生注解,在@SpringBootApplication中有一個(gè)注解@EnableAutoConfiguration,翻譯成人話就是開(kāi)啟自動(dòng)配置,其定義如下:

          而這個(gè)注解也是一個(gè)派生注解,其中的關(guān)鍵功能由@Import提供。
          其導(dǎo)入的AutoConfigurationImportSelector的selectImports()方法通過(guò)SpringFactoriesLoader.loadFactoryNames()掃描所有具有META-INF/spring.factories的jar包。spring-boot-autoconfigure-x.x.x.x.jar里就有一個(gè)這樣的spring.factories文件。
          這個(gè)spring.factories文件也是一組一組的key=value的形式,其中一個(gè)key是EnableAutoConfiguration類的全類名,而它的value是一個(gè)xxxxAutoConfiguration的類名的列表,這些類名以逗號(hào)分隔,如下圖所示:

          這個(gè)@EnableAutoConfiguration注解通過(guò)@SpringBootApplication被間接的標(biāo)記在了Spring Boot的啟動(dòng)類上。在SpringApplication.run(...)的內(nèi)部就會(huì)執(zhí)行selectImports()方法,找到所有JavaConfig自動(dòng)配置類的全限定名對(duì)應(yīng)的class,然后將所有自動(dòng)配置類加載到Spring容器中。

          自動(dòng)配置生效

          每一個(gè)XxxxAutoConfiguration自動(dòng)配置類都是在某些條件之下才會(huì)生效的,這些條件的限制在Spring Boot中以注解的形式體現(xiàn),常見(jiàn)的條件注解有如下幾項(xiàng):
          @ConditionalOnBean:當(dāng)容器里有指定的bean的條件下。
          @ConditionalOnMissingBean:當(dāng)容器里不存在指定bean的條件下。
          @ConditionalOnClass:當(dāng)類路徑下有指定類的條件下。
          @ConditionalOnMissingClass:當(dāng)類路徑下不存在指定類的條件下。
          @ConditionalOnProperty:指定的屬性是否有指定的值,比如@ConditionalOnProperties(prefix=”xxx.xxx”, value=”enable”, matchIfMissing=true),代表當(dāng)xxx.xxx為enable時(shí)條件的布爾值為true,如果沒(méi)有設(shè)置的情況下也為true。
          以ServletWebServerFactoryAutoConfiguration配置類為例,解釋一下全局配置文件中的屬性如何生效,比如:server.port=8081,是如何生效的(當(dāng)然不配置也會(huì)有默認(rèn)值,這個(gè)默認(rèn)值來(lái)自于org.apache.catalina.startup.Tomcat)。

          在ServletWebServerFactoryAutoConfiguration類上,有一個(gè)@EnableConfigurationProperties注解:開(kāi)啟配置屬性,而它后面的參數(shù)是一個(gè)ServerProperties類,這就是習(xí)慣優(yōu)于配置的最終落地點(diǎn)。

          在這個(gè)類上,我們看到了一個(gè)非常熟悉的注解:@ConfigurationProperties,它的作用就是從配置文件中綁定屬性到對(duì)應(yīng)的bean上,而@EnableConfigurationProperties負(fù)責(zé)導(dǎo)入這個(gè)已經(jīng)綁定了屬性的bean到spring容器中(見(jiàn)上面截圖)。那么所有其他的和這個(gè)類相關(guān)的屬性都可以在全局配置文件中定義,也就是說(shuō),真正“限制”我們可以在全局配置文件中配置哪些屬性的類就是這些XxxxProperties類,它與配置文件中定義的prefix關(guān)鍵字開(kāi)頭的一組屬性是唯一對(duì)應(yīng)的。
          至此,我們大致可以了解。在全局配置的屬性如:server.port等,通過(guò)@ConfigurationProperties注解,綁定到對(duì)應(yīng)的XxxxProperties配置實(shí)體類上封裝為一個(gè)bean,然后再通過(guò)@EnableConfigurationProperties注解導(dǎo)入到Spring容器中。
          而諸多的XxxxAutoConfiguration自動(dòng)配置類,就是Spring容器的JavaConfig形式,作用就是為Spring 容器導(dǎo)入bean,而所有導(dǎo)入的bean所需要的屬性都通過(guò)xxxxProperties的bean來(lái)獲得。
          可能到目前為止還是有所疑惑,但面試的時(shí)候,其實(shí)遠(yuǎn)遠(yuǎn)不需要回答的這么具體,你只需要這樣回答:
          Spring Boot啟動(dòng)的時(shí)候會(huì)通過(guò)@EnableAutoConfiguration注解找到META-INF/spring.factories配置文件中的所有自動(dòng)配置類,并對(duì)其進(jìn)行加載,而這些自動(dòng)配置類都是以AutoConfiguration結(jié)尾來(lái)命名的,它實(shí)際上就是一個(gè)JavaConfig形式的Spring容器配置類,它能通過(guò)以Properties結(jié)尾命名的類中取得在全局配置文件中配置的屬性如:server.port,而XxxxProperties類是通過(guò)@ConfigurationProperties注解與全局配置文件中對(duì)應(yīng)的屬性進(jìn)行綁定的。
          通過(guò)一張圖標(biāo)來(lái)理解一下這一繁復(fù)的流程:

           圖片來(lái)自于王福強(qiáng)老師的博客:https://afoo.me/posts/2015-07-09-how-spring-boot-works.html
          綜上是對(duì)自動(dòng)配置原理的講解。當(dāng)然,在瀏覽源碼的時(shí)候一定要記得不要太過(guò)拘泥與代碼的實(shí)現(xiàn),而是應(yīng)該抓住重點(diǎn)脈絡(luò)。
          一定要記得XxxxProperties類的含義是:封裝配置文件中相關(guān)屬性;XxxxAutoConfiguration類的含義是:自動(dòng)配置類,目的是給容器中添加組件。
          而其他的主方法啟動(dòng),則是為了加載這些五花八門(mén)的XxxxAutoConfiguration類。

          END


          推薦閱讀

          一鍵生成Springboot & Vue項(xiàng)目!【畢設(shè)神器】

          Java可視化編程工具系列(一)

          Java可視化編程工具系列(二)


          順便給大家推薦一個(gè)GitHub項(xiàng)目,這個(gè) GitHub 整理了上千本常用技術(shù)PDF,絕大部分核心的技術(shù)書(shū)籍都可以在這里找到,

          GitHub地址:https://github.com/javadevbooks/books

          Gitee地址:https://gitee.com/javadevbooks/books

          電子書(shū)已經(jīng)更新好了,你們需要的可以自行下載了,記得點(diǎn)一個(gè)star,持續(xù)更新中..



          瀏覽 41
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产一卡二无码 | 日批视频大全在线 | 亚洲性爱手机 | 国产极度色诱视频在线观看 | 性免费网站 |