springboot源碼@SpringBootApplication註解分析

首先是@SpringBootApplication(自動化裝配功能)

點進去源碼發現html

 

 

 先來看看每一個註解的意思java

能夠發現它是由衆多註解組合而成的,下面具體分析下這裏每一個註解所起到的做用。spring

  • @Target Target經過ElementType來指定註解可以使用範圍的枚舉集合(FIELD/METHOD/PARAMETER...)
  • @Retention Retention(保留)註解說明,這種類型的註解會被保留到那個階段. 有三個值:springboot

    • RetentionPolicy.SOURCE —— 這種類型的Annotations只在源代碼級別保留,編譯時就會被忽略
    • RetentionPolicy.CLASS —— 這種類型的Annotations編譯時被保留,在class文件中存在,但JVM將會忽略
    • RetentionPolicy.RUNTIME —— 這種類型的Annotations將被JVM保留,因此他們能在運行時被JVM或其餘使
  • @Documented 註解代表這個註解應該被 javadoc工具記錄. 默認狀況下,javadoc是不包括註解的. 但若是聲明註解時指定了 @Documented,則它會被 javadoc 之類的工具處理, 因此註解類型信息也會被包括在生成的文檔中
  • @Inherited 容許子類繼承父類的註解,僅限於類註解有用,對於方法和屬性無效。
  • @SpringBootConfiguration 註解實際上和@Configuration有相同的做用,配備了該註解的類就可以以JavaConfig的方式完成一些配置,能夠再也不使用XML配置。
  • @ComponentScan 這個註解完成的是自動掃描的功能,至關於Spring XML配置文件中的:<context:component-scan>,可以使用basePackages屬性指定要掃描的包,及掃描的條件。若是不設置則默認掃描@ComponentScan註解所在類的同級類和同級目錄下的全部類,因此咱們的Spring Boot項目,通常會把入口類放在頂層目錄中,這樣就可以保證源碼目錄下的全部類都可以被掃描到。
  • @EnableAutoConfiguration 這個註解是讓Spring Boot的配置可以如此簡化的關鍵性註解。app

 

其實主要重要的註解就是標紅的這三個註解:下面咱們着重分析這三個註解。框架

1)@ComponentScan:就像上面所說,ComponentScan通常在spring中主要是用於:maven

@ComponentScan用於類或接口上主要是指定掃描路徑,spring會把指定路徑下帶有指定註解的類自動裝配到bean容器裏,會被自動裝配的註解包括@Controller、@Service、@Component、@Repository等等,其做用等同於<context:component-scan base-package="com.maple.learn" />配置。ide

而在springboot中,若是你的其餘包都在使用了@SpringBootApplication註解的main app所在的包及其下級包,則你什麼都不用作,SpringBoot會自動幫你把其餘包都掃描了,若是你有一些bean所在的包,不在main app的包及其下級包,那麼你須要手動加上@ComponentScan註解並指定那個bean所在的包。(後面在解釋在這裏的原理spring-boot

 

2)@SpringBootConfiguration :先來一張其源碼截圖工具

 

 這裏說明SpringBootConfiguration 實際上是對spring的@Configuration的封裝,至關於一個配置類,註解主要標註在某個類上,至關於xml配置文件中的<beans>。並會將當前類內聲明的一個或多個以@Bean註解的方法的實例歸入到spring容器中,而且實例名就是方法名。自己其實也是一個IoC容器的配置類

3)@EnableAutoConfiguration 這個纔是重點,點擊源碼發現

 先來聊聊這個註解:@AutoConfigurationPackage

AutoConfigurationPackage註解的做用是將 添加該註解的類所在的package 做爲 自動配置package 進行管理。

AutoConfigurationPackage註解:

複製代碼
複製代碼
1     static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
2 
3         @Override
4         public void registerBeanDefinitions(AnnotationMetadata metadata,
5                 BeanDefinitionRegistry registry) {
6             register(registry, new PackageImport(metadata).getPackageName());
7         }
複製代碼
複製代碼

它實際上是註冊了一個Bean的定義。

new PackageImport(metadata).getPackageName(),它其實返回了當前主程序類的 同級以及子級     的包組件。

以上圖爲例,DemoApplication是和demo包同級,可是demo2這個類是DemoApplication的父級,和example包同級

也就是說,DemoApplication啓動加載的Bean中,並不會加載demo2,這也就是爲何,咱們要把DemoApplication放在項目的最高級中。

 

這裏來談談其與componentScan的區別:

在默認的狀況下就是將:主配置類(@SpringBootApplication)的所在包及其子包裏邊的組件掃描到Spring容器中。

  • 看完這句話,會不會以爲,這不就是ComponentScan的功能嗎?這倆不就重複了嗎?

        看看文檔的這句話:

it will be used when scanning for code @Entity classes.
It is generally recommended that you place EnableAutoConfiguration (if you’re
not using @SpringBootApplication) in a root package so that all sub-packages
and classes can be searched.

好比說,你用了Spring Data JPA,可能會在實體類上寫@Entity註解。這個@Entity註解由@AutoConfigurationPackage掃描並加載,而咱們平時開發用的@Controller/@Service/@Component/@Repository這些註解是由ComponentScan來掃描並加載的。

簡單理解:這兩者掃描的對象是不同的。

 4)下面來看看一個重中之重的註解:@EnableAutoConfiguration

老規矩進行這個重要註解以前,要先鋪墊一些其用到的知識,否則的話,不能到時候懵懵懂懂的。接下來看看這個@Import這個註解,他是來幹什麼的呢?

@Import註釋,根據字義,咱們能夠理解爲導入組件選擇器自動配置,做用是將須要導入的組件以全類名的方式返回,這些組件將被添加到Spring容器中,如圖:

自動配置類的做用,配置注入功能組件自動完成。

a.容許使用@Configuration註解的類

這個比較簡單,若是明確知道須要引入哪一個配置類,直接引入就能夠。

b.容許是實現ImportSelector接口的類

若是並不肯定引入哪一個配置類,須要根據@Import註解所標識的類或者另外一個註解(一般是註解)裏的定義信息選擇配置類的話,用這種方式。

c.Spring會把實現ImportSelector接口的類中的SelectImport方法返回的值注入到Spring容器中(即IOC容器)。這個方法的返回值必須是一個class的全類名的String[]。
比較典型的註解:

 

好吧,簡單瞭解這個以後,下面來談談重點吧:

@EnableAutoConfiguration剛纔已經貼了一張圖了,點開源碼以後就是

繼續點擊進去,你會發現:

 

 

 

 

 

 

 

 

 一路點下去,發現AutoConfigurationImportSelector實現了父類接口ImportSelector,而且重寫了父類的selectImports的方法。

 

 在這個方法中,其實主要實現是看configurations這個裏面返回的是什麼東西就好了。

繼續點進去這個方法

 

 繼續點擊進去

 

 這個時候,咱們就豁然開朗了,原來最終咱們是要找「META-INF/spring.factories」這個配置文件啊!

可是這個東西實在哪裏呢,來看看咱們引入的mavenjar包吧。

 

 原來是這個東西,看看裏面是什麼

 

 是否是明白了,***AutoConfiguration,這個不就是咱們上面的註解的形式嗎?

上圖裏面這麼多的xxxAutoConfiguration就是咱們的這麼久得出的結果,最終就是加載這麼多的類的全路徑,而後springboot內部就是實例化這些類並加載到容器裏面,完成springboot應用啓動時的自動配置。

來看看下面這樣圖,他們大神畫的生動的圖,讓人豁然開朗:

 

 

 

自動配置幕後英雄:SpringFactoriesLoader詳解

藉助於Spring框架原有的一個工具類:SpringFactoriesLoader的支持,@EnableAutoConfiguration能夠智能的自動配置功效才得以大功告成!

SpringFactoriesLoader屬於Spring框架私有的一種擴展方案,其主要功能就是從指定的配置文件META-INF/spring.factories加載配置。

複製代碼
public abstract class SpringFactoriesLoader {
    //...
    public static <T> List<T> loadFactories(Class<T> factoryClass, ClassLoader classLoader) {
        ...
    }


    public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
        ....
    }
}
複製代碼

配合@EnableAutoConfiguration使用的話,它更可能是提供一種配置查找的功能支持,即根據@EnableAutoConfiguration的完整類名org.springframework.boot.autoconfigure.EnableAutoConfiguration做爲查找的Key,獲取對應的一組@Configuration類

上圖就是從SpringBoot的autoconfigure依賴包中的META-INF/spring.factories配置文件中摘錄的一段內容,能夠很好地說明問題。

因此,@EnableAutoConfiguration自動配置的魔法騎士就變成了:從classpath中搜尋全部的META-INF/spring.factories配置文件,並將其中org.springframework.boot.autoconfigure.EnableutoConfiguration對應的配置項經過反射(Java Refletion)實例化爲對應的標註了@Configuration的JavaConfig形式的IoC容器配置類,而後彙總爲一個並加載到IoC容器。

 在來探討一個問題:springboot的啓動類其實基本上就兩部分,一部分是spring-boot-starter,另外一部分是spring-boot-autoconfig,starter裏面其實沒有什麼東西,就是依賴了autoconfig。

 

 

這麼多的***AutoConfiguration,點進去過去會自動調到對應的啓動類源碼,在啓動類中還有一個配置類***Properties,這個是默認自帶的,例如:這個是activemq的默認配置類(默認的配置類)

 

 

 

 在這裏,ActiveMQAutoConfiguration的源碼會關聯這個配置文件,這樣他們就能夠連在一塊兒,最直接的體現就是,咱們在application.properties或者applciation.yml中能夠提示配置文件的屬性

 

這樣的話,整個啓動類的思路就比較清晰了。

總結:

@ConditionalOnXX 條件判斷註解,經過條件來判斷這個類是否生效!

 

 隨便拿一個啓動器舉例子:

 

 

 1:springboot啓動的時候會加載大量的自動配置類。spring.factories

 2:咱們就須要判斷咱們的類是否在這個裏面,若是不存在,咱們須要手動導入,若是存在,導入啓動器便可。

 3:咱們的配置文件(application.yml或者application.properties)之因此能夠自動配置生效:

       (1)xxxAutoConfiguation:自動配置類,根據條件@ConditionalOnXX來進行判斷是否生效,若是生效則成功注入bean

       (2)xxxProperties:封裝配置文件的相關屬性

4:給容器中自動配置屬性的時候,會經過xxxProperties來獲取某用戶的配置文件中的屬性,若是沒有則使用默認,有則使用本身配置的。

(未完待續........)

 

 


本文引用文章聲明:
原文連接:https://blog.csdn.net/neulily2005/article/details/83750027 -------CSDN博主「Mr.甘」

原文連接:https://blog.csdn.net/mapleleafforest/article/details/86623578----------CSDN博主「a maple leaf」

原文連接:http://www.javashuo.com/article/p-conjyivq-ey.html------那啥快看[博客園]

原文連接:http://www.imooc.com/article/275453?block_id=tuijian_wz---Java3y[慕課網]

原文連接:http://www.javashuo.com/article/p-vofmtakc-gy.html

相關文章
相關標籤/搜索