@SpringBootApplication 注解詳解以及執行流程


@SpringBootApplication  : 是Sprnig Boot項目的核心注解,目的是開啟自動配置

 

目錄

@SpringBootApplication  : 是Sprnig Boot項目的核心注解,目的是開啟自動配置

(一)、@ComponentScan 注解

(二)、@EnableAutoConfiguration 注解

(三)、@SpringBootConfiguration 注解

(四)、@Inherited 注解

聲明的此注解使用了Inherited元注解,表示此注解用在類上時,會被子類所繼承

(五)、@Documented 注解

(六)、@Retention() 注解

(七)、@Target()  注解

                     深入探索SpringApplication執行流程

 

spingboot建議的目錄結果如下:

root package結構:com.example.myproject


大家可以先認識一下@interface  : java 中@interface 和interface 的區別

(一)、@ComponentScan 注解


    
    
    
            
  1. @ComponentScan(excludeFilters = {
  2. @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
  3. @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

1、@ComponentScan這個注解在Spring中很重要,它對應XML配置中的元素,@ComponentScan的功能其實就是自動掃描並加載符合條件的組件(比如@Component和@Repository等)或者bean定義,最終將這些bean定義加載到IoC容器中。

我們可以通過basePackages等屬性來細粒度的定制@ComponentScan自動掃描的范圍,如果不指定,則默認Spring框架實現會從聲明@ComponentScan所在類的package進行掃描。

注:所以SpringBoot的啟動類最好是放在root package下,因為默認不指定basePackages。

2、@ComponentScan告訴Spring 哪個packages 的用注解標識的類 會被spring自動掃描並且裝入bean容器。

例如,如果你有個類用@Controller注解標識了,那么,如果不加上@ComponentScan,自動掃描該controller,那么該Controller就不會被spring掃描到,更不會裝入spring容器中,因此你配置的這個Controller也沒有意義。

3、參數的作用


    
    
    
            
  1. basePackageClasses:對 basepackages()指定掃描注釋組件包類型安全的替代。
  2. excludeFilters:指定不適合組件掃描的類型。
  3. includeFilters:指定哪些類型有資格用於組件掃描。
  4. lazyInit:指定是否應注冊掃描的 beanslazy初始化。
  5. nameGenerator:用於在 Spring容器中的檢測到的組件命名。
  6. resourcePattern:控制可用於組件檢測的類文件。
  7. scopedProxy:指出代理是否應該對檢測元件產生,在使用過程中會在代理風格時尚的范圍是必要的。
  8. scopeResolver:用於解決檢測到的組件的范圍。
  9. useDefaultFilters:指示是否自動檢測類的注釋

(二)、@EnableAutoConfiguration 注解

@EnableAutoConfiguration 簡單概括一下就是,借助@Import的支持,收集和注冊特定場景相關的bean定義

  • @EnableScheduling是通過@Import將Spring調度框架相關的bean定義都加載到IoC容器。
  • @EnableMBeanExport是通過@Import將JMX相關的bean定義加載到IoC容器。

而@EnableAutoConfiguration也是借助@Import的幫助,將所有符合自動配置條件的bean定義加載到IoC容器,僅此而已!

@EnableAutoConfiguration作為一個復合Annotation,其自身定義關鍵信息如下:

其中,最關鍵的要屬@Import(AutoConfigurationImportSelector.class),借助AutoConfigurationImportSelector,@EnableAutoConfiguration可以幫助SpringBoot應用將所有符合條件的@Configuration配置都加載到當前SpringBoot創建並使用的IoC容器。

              

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

        配合@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容器。

(三)、@SpringBootConfiguration 注解


    
    
    
            
  1. @SpringBootConfiguration繼承自 @Configuration,二者功能也一致,標注當前類是配置類,
  2. 並會將當前類內聲明的一個或多個以 @Bean注解標記的方法的實例納入到spring容器中,並且實例名就是方法名。

(四)、@Inherited 注解

關於java中元注解Inherited 的使用說明

首先解釋下元注解,就是用來中聲明注解類型時需要使用到的注解。

Inherited作用是,使用此注解聲明出來的自定義注解,在使用此自定義注解時,如果注解在類上面時,子類會自動繼承此注解,否則的話,子類不會繼承此注解。這里一定要記住,使用Inherited聲明出來的注解,只有在類上使用時才會有效,對方法,屬性等其他無效。

聲明的此注解使用了Inherited元注解,表示此注解用在類上時,會被子類所繼承

(五)、@Documented 注解

        Documented注解表明這個注釋是由 javadoc記錄的,在默認情況下也有類似的記錄工具。 如果一個類型聲明被注釋了文檔化,它的注釋成為公共API的一部分。

(六)、@Retention() 注解

RetentionPolicy這個枚舉類型的常量描述保留注釋的各種策略,它們與元注釋(@Retention)一起指定注釋要保留多長時間

(七)、@Target()  注解

ElementType 這個枚舉類型的常量提供了一個簡單的分類:注釋可能出現在Java程序中的語法位置(這些常量與元注釋類型(@Target)一起指定在何處寫入注釋的合法位置)

===========================================================================================

===========================================================================================

                     深入探索SpringApplication執行流程

SpringApplication的run方法的實現是我們本次旅程的主要線路,該方法的主要流程大體可以歸納如下:

1) 如果我們使用的是SpringApplication的靜態run方法,那么,這個方法里面首先要創建一個SpringApplication對象實例,然后調用這個創建好的SpringApplication的實例方法。在SpringApplication實例初始化的時候,它會提前做幾件事情:

  • 根據classpath里面是否存在某個特征類(org.springframework.web.context.ConfigurableWebApplicationContext)來決定是否應該創建一個為Web應用使用的ApplicationContext類型。

  • 使用SpringFactoriesLoader在應用的classpath中查找並加載所有可用的ApplicationContextInitializer。

  • 使用SpringFactoriesLoader在應用的classpath中查找並加載所有可用的ApplicationListener。

  • 推斷並設置main方法的定義類。

2) SpringApplication實例初始化完成並且完成設置后,就開始執行run方法的邏輯了,方法執行伊始,首先遍歷執行所有通過SpringFactoriesLoader可以查找到並加載的SpringApplicationRunListener。調用它們的started()方法,告訴這些SpringApplicationRunListener,“嘿,SpringBoot應用要開始執行咯!”。

3) 創建並配置當前Spring Boot應用將要使用的Environment(包括配置要使用的PropertySource以及Profile)。

4) 遍歷調用所有SpringApplicationRunListener的environmentPrepared()的方法,告訴他們:“當前SpringBoot應用使用的Environment准備好了咯!”。

5) 如果SpringApplication的showBanner屬性被設置為true,則打印banner。   【banner:英文廣告橫幅,在這里面指的是運行時輸出的SpringBoot,還可以進行修改

                                         

6) 根據用戶是否明確設置了applicationContextClass類型以及初始化階段的推斷結果,決定該為當前SpringBoot應用創建什么類型的ApplicationContext並創建完成,然后根據條件決定是否添加ShutdownHook,決定是否使用自定義的BeanNameGenerator,決定是否使用自定義的ResourceLoader,當然,最重要的,將之前准備好的Environment設置給創建好的ApplicationContext使用。  【ShutdownHook :停止服務

7) ApplicationContext創建好之后,SpringApplication會再次借助Spring-FactoriesLoader,查找並加載classpath中所有可用的ApplicationContext-Initializer,然后遍歷調用這些ApplicationContextInitializer的initialize(applicationContext)方法來對已經創建好的ApplicationContext進行進一步的處理。

8) 遍歷調用所有SpringApplicationRunListener的contextPrepared()方法。

9) 最核心的一步,將之前通過@EnableAutoConfiguration獲取的所有配置以及其他形式的IoC容器配置加載到已經准備完畢的ApplicationContext。

10) 遍歷調用所有SpringApplicationRunListener的contextLoaded()方法。

11) 調用ApplicationContext的refresh()方法,完成IoC容器可用的最后一道工序。

12) 查找當前ApplicationContext中是否注冊有CommandLineRunner,如果有,則遍歷執行它們。

13) 正常情況下,遍歷執行SpringApplicationRunListener的finished()方法、(如果整個過程出現異常,則依然調用所有SpringApplicationRunListener的finished()方法,只不過這種情況下會將異常信息一並傳入處理)

去除事件通知點后,整個流程如下:

                 

                           

 

參考:

1、Spring Boot干貨系列:(三)啟動原理解析

2、@componentscan注解的用法和作用 

3、excludeFilters:  

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/ComponentScan.html#excludeFilters--

4、@SpringBootConfiguration注解

5、關於java 注解中元注解Inherited的使用詳解

6、Java注解之 @Target、@Retention、@Documented簡介

參考:https://blog.csdn.net/qq_28289405/article/details/81302498#%EF%BC%88%E4%B8%80%EF%BC%89%E3%80%81%40ComponentScan%20%E6%B3%A8%E8%A7%A3


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM