<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 系列 02

          共 3526字,需瀏覽 8分鐘

           ·

          2020-08-19 22:35

          閱讀全文,約 8?分鐘


          這是江帥帥的第002篇原創(chuàng)



          1 @SpringBootApplication 注解

          Spring Boot 的啟動(dòng)類,也就是入口類,需要使用?@SpringBootApplication?注解來標(biāo)注。在啟動(dòng)類中,我們的 main 方法就是 Java 應(yīng)用程序的入口方法。

          @SpringBootApplication 是一個(gè)組合注解,具體源碼如下:


          其中,比較重要的三個(gè)注解是:@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan。


          2 @SpringBootConfiguration 注解


          主要是負(fù)責(zé) Spring Boot 應(yīng)用配置相關(guān)的注解,它也是組合注解,具體源碼如下:



          通過源碼,可以看到它也使用了 @Configuration 注解,它們兩個(gè)都是將當(dāng)前類標(biāo)注為配置類,能將類中使用 @Bean 注解標(biāo)記的方法對應(yīng)的實(shí)例注入到 Spring 容器中,那實(shí)例名就是方法名。


          另外在 @Configuration 注解源碼中,還看到有一個(gè) @Component 注解,做了再次封裝,主要是把普通 POJO 實(shí)例化到 Spring 容器中。具體源碼如下:



          所以,更推薦大家在 Spring Boot 應(yīng)用中使用 @SpringBootConfiguration。


          3 @EnableAutoConfiguration 注解


          主要用來啟動(dòng)自動(dòng)配置,Spring Boot 就能夠根據(jù)依賴信息自動(dòng)實(shí)現(xiàn)應(yīng)用的相關(guān)配置,總體分為兩個(gè)部分:一是收集所有 spring.factories 中EnableAutoConfiguration 相關(guān) bean 的類,二是將得到的類注冊到 Spring 容器中。將符合的配置都加載到 IoC 容器中。具體源碼如下:



          組件調(diào)用關(guān)系圖,具體如下:


          這張圖,怎么去理解呢?其實(shí)是這樣的,涉及到了 BeanFactory 的創(chuàng)建。Spring 框架中會(huì)調(diào)用 ApplicationContext 的 refresh 方法來啟動(dòng) Spring 容器,然后就會(huì)創(chuàng)建 BeanFactory,接著掃描各種包,讀取使用到了 @Configuration、@Import、@SpringBootApplication 等注解標(biāo)注的類,然后生成 BeanDefinition 最終注冊到 BeanFactory 中。


          然后就交給 BeanFactoryPostProcessor 來執(zhí)行,BeanFactory 后置處理器會(huì)處理 BeanDefinition,比如在 BeanFactoryPostProcessor 接口中,提供了 postProcessBeanFactory 方法來接收 ConfigurableListableBeanFactory 對象來處理。具體源碼如下:



          其他類似 @Configuration 等配置性質(zhì)的注解,就讓 ConfigurationClassPostProcessor 來處理。


          上面的 ConfigurationClassPostProcessor 主要是 BeanFactoryPostProcessor 接口的實(shí)現(xiàn)類,主要是想從 BeanFactory 中獲取所有 BeanDefinition 列表,遍歷出那些使用了 @Configuration、@Import 等配置性質(zhì)注解標(biāo)注的類所對應(yīng)的 BeanDefintion,然后進(jìn)行注冊。具體源碼如下:



          具體,我們還可以去看看它的 parse 方法是如何處理的,它會(huì)去解析注解。



          看到最后的 deferredImportSelectorHandler,這個(gè)內(nèi)部類的里面有一個(gè) deferredImportSelectors 集合,主要是用來添加 AutoConfigurationImportSelector。這個(gè)內(nèi)部私有類,主要維護(hù)了一個(gè)類型為DeferredImportSelectorHolder 的 deferredImportSelectors 列表。這最后一句代碼,就是處理完其他BeanDefinitions 后調(diào)用 process 方法。


          再接著來看 process 方法,它負(fù)責(zé)自動(dòng)配置類導(dǎo)入的內(nèi)部實(shí)現(xiàn),具體源碼如下:



          這個(gè)方法,需要這么來理解:


          首先,DeferredImportSelector 它會(huì)去從 spring-boot-autoconfigure 包路徑下的 META-INF/spring.factories 文件中找到 EnableAutoConfiguration 作為 key,然后獲取對應(yīng)的自動(dòng)配置類列表。


          第二步,在里面通過 key 即可找到對應(yīng)需要自動(dòng)配置的類。接著會(huì)進(jìn)行遍歷所有類名,加載和導(dǎo)入對應(yīng)的配置類。


          大致的思路是會(huì)先創(chuàng)建一個(gè) ConfigurationClass 的對象,它會(huì)包含當(dāng)前這個(gè)配置類,然后傳進(jìn)被調(diào)用的 doProcessConfigurationClass 方法中,然后處理該類包含的注解。如果是 @Import 注解,則會(huì)放在 processImports 方法中進(jìn)行處理。


          再具體講,就是那些非 ImportSelector 接口實(shí)現(xiàn)類和ImportBeanDefinitionRegistrar 接口實(shí)現(xiàn)類的配置類,就會(huì)調(diào)用processConfigurationClass 方法來處理該自動(dòng)配置類上面的其他注解,并將該自動(dòng)配置類內(nèi)部使用了 @Bean 注解的所有方法,條件化生成 bean 并注冊到 Spring 容器,那最終就可以提供特定功能組件的默認(rèn)實(shí)現(xiàn),也就實(shí)現(xiàn)了 SpringBoot 的自動(dòng)配置功能,在你使用的時(shí)候,比如直接通過 @Autowried 注解就可以注入某個(gè)功能組件,而不需要顯示配置。


          具體源碼如下(這里不貼全部源碼了,大家可以看看它給出的注釋就明白了):



          4 獲取 Bean 類信息

          我們可以來研究下這個(gè)注解,了解它是如何加載配置的。在源碼中,可以看到 @Import({AutoConfigurationImportSelector.class}) 注解,導(dǎo)入的就是自動(dòng)配置選擇器。


          AutoConfigurationImportSelector 選擇器是 DeferredImportSelector 接口的實(shí)現(xiàn)類,會(huì)在 BeanFactory 中對所有 BeanDefinition 處理后執(zhí)行來進(jìn)行 SpringBoot 自動(dòng)配置類的加載、導(dǎo)入操作等,并基于 @Conditional 條件化配置來決定是否將該配置類內(nèi)部定義的 Bean 注冊到 Spring 容器。具體源碼如下:



          在 AutoConfigurationImportSelector.class 中,可以看到實(shí)現(xiàn)了一個(gè) selectImports 方法,用來導(dǎo)出 Configuration。方法中調(diào)用了 getAutoConfigurationEntry 方法,獲取 bean 類信息。具體源碼如下:



          繼續(xù)來看?getAutoConfigurationEntry?方法,具體源碼如下:



          再接著來看調(diào)用的?getCandidateConfigurations?方法,它主要是想獲取所有對應(yīng)的配置,它里面調(diào)用了?loadFactoryNames?方法,目的是要想加載?spring.factories?文件。它們的源碼具體如下:



          loadFactoryNames 方法的具體源碼如下:



          接著就在?loadSpringFactories?方法中,找到所有的?spring.factories?配置信息,然后全部返回。具體源碼如下:



          未完待續(xù),等我下一篇嗷 ~~~


          轉(zhuǎn)自公眾號:江帥帥(ID:NXJSS666)




          ?--END--


          ? 推薦

          公眾號ID|javabaiwen

          小編微信|619531440


          每天分享技術(shù)干貨

          視頻 | 電子書 | 面試題?|?開發(fā)經(jīng)驗(yàn)

          瀏覽 56
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

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

          手機(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>
                  精品中字幕久久久人妻 | 亚洲秘 无码一区二区三区密桃 | 欧美一级黄片免费看 | 欧美+国产+无码+麻豆 | 午夜激情亚洲无码 |