Spring Boot運行原理

版權聲明:本文爲CSDN博主「大神,快來碗裏」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://blog.csdn.net/cowbin2012/article/details/88861160面試

 

Spring Boot方式的項目開發已經逐步成爲Java應用開發領域的主流框架,它不只能夠方便地建立生產級的Spring應用程序,還能輕鬆地經過一些註解配置與目前比較流行的微服務框架SpringCloud快速地集成。

在咱們實際使用Spring Boot進行項目開發的過程當中,每每只須要幾個很簡單的註解配置就可以將應用啓動運行了,相比於傳統的Spring項目而已,這種提高大大地提升了咱們的研發效率。然而,這種便捷性則是經過高度地上層封裝來實現的,如:大量的註解封裝、約定大於配置的原則等手段。因此,也許你已經使用Spring Boot開發不少個項目了,但對Spring Boot的運行原理真的搞清楚了嗎?若是,面試中有人問你Spring Boot的實現原理是什麼?你能正確地回答出來嗎?

與大部分其餘框架及技術的使用場景同樣,咱們每每過多地專一於使用層面,以便快速地完成業務開發,卻每每忽略了對框架底層運行原理的關注,因此面試中被懟也就不足爲奇了。不過不要緊,在今天的文章中,小碼哥將爲你們全方位地梳理下Spring Boot的底層運行原理,並經過圖文結合的方式給你們進行展現,但願對您的工做或者面試可以有所幫助!
Spring Boot運行原理

實際上Spring Boot並非要替代Spring框架,咱們知道在JDK1.5推出註解功能之後,Spring框架實現了大量的註解來替代原有的基於XML的配置,主要用於配置管理、Bean的注入以及AOP等相關功能的實現。然而,隨着Spring註解的數量愈來愈多,而且被大量的使用,尤爲是相同的多個註解會被大量重複地用到各個類或者方法中。這樣就致使了繁瑣的配置及大量冗餘的代碼。

到這裏你也許就會想到既然這麼多Spring註解很繁瑣,那麼可不能夠將其組合一下呢?經過定義一些新的註解,將功能進行分類,不一樣的Spring註解經過新的註解定義進行必定的組合,這樣對於大部分通用場景下,只須要引入一個新的註解,就自動包含了與之相關的其餘Spring註解?沒錯!Spring Boot說到底就是這麼個玩意!

可是,要實現註解的組合並非簡單的把多個註解牽強的疊加在一塊兒,這裏涉及到一些編程語言上的實現,例如要組合一個註解,那麼該註解是否支持註解到別的註解上呢(略微有點拗口)?還有若是組合註解後,由於註解的背後還涉及到Spring容器上下文的初始化以及Bean注入相關的邏輯,若是一個A註解涉及的Bean,涉及到另一個B註解涉及到的Bean的初始化;也就意味着A註解的Bean初始化,須要在B註解的Bean初始化完成後才能進行注入,不然就會致使Bean依賴注入的失敗。

Spring Boot框架本質上就是經過組合註解的方式實現了諸多Spring註解的組合,從而極大地簡化了Spring框架自己的繁瑣配置,實現快速的集成和開發。只是要這樣實現,也須要必定的基礎條件!
元註解

說到底Spring Boot框架是在Spring框架的基礎上作了一層二次封裝,最重要的特色就是Spring Boot框架定義了一些新的註解來實行一些Spring註解的組合,而Spring註解則是基於JDK1.5+後的註解功能的支持來完成的。

關於JDK的註解若是想要註解到別的註解上,就須要將其定義爲元註解,所謂的元註解,就是能夠註解到其餘註解上的註解,被註解的註解就是咱們上面說到的組合註解。而Spring框架的不少註解都是能夠做爲元註解的,而且Spring框架自己也實現了不少組合註解,例如咱們經常使用的註解@Configuration就是一個這樣的組合註解。所以,有了這樣一個條件Spring Boot的實現纔有了基礎條件!

條件註解@Conditional

Spring 4提供了一個通用的基於條件的註解@Conditional。該註解能夠根據知足某一個特定條件與否來決定是否建立某個特定的Bean,例如,某個依賴包jar在一個類路徑的時候,自動配置一個或多個Bean時,能夠經過註解@Conditional註解來實現只有某個Bean被建立時纔會建立另一個Bean,這樣就能夠依據特定的條件來控制Bean的建立行爲,這樣的話咱們就能夠利用這樣一個特性來實現一些自動的配置。

而這一點對於Spring Boot實現自動配置來講是一個核心的基礎能力,從本質上來講Spring Boot之因此能夠實現自動註解配置很大程度上也是基於這一能力。在Spring Boot中以@Conditional爲元註解又從新定義了一組針對不一樣場景的組合條件註解,它們分別是:

@ConditionalOnBean:當容器中有指定Bean的條件下進行實例化。

@ConditionalOnMissingBean:當容器裏沒有指定Bean的條件下進行實例化。

@ConditionalOnClass:當classpath類路徑下有指定類的條件下進行實例化。

@ConditionalOnMissingClass:當類路徑下沒有指定類的條件下進行實例化。

@ConditionalOnWebApplication:當項目是一個Web項目時進行實例化。

@ConditionalOnNotWebApplication:當項目不是一個Web項目時進行實例化。

@ConditionalOnProperty:當指定的屬性有指定的值時進行實例化。

@ConditionalOnExpression:基於SpEL表達式的條件判斷。

@ConditionalOnJava:當JVM版本爲指定的版本範圍時觸發實例化。

@ConditionalOnResource:當類路徑下有指定的資源時觸發實例化。

@ConditionalOnJndi:在JNDI存在的條件下觸發實例化。

@ConditionalOnSingleCandidate:當指定的Bean在容器中只有一個,或者有多個可是指定了首選的Bean時觸發實例化。

縱觀Spring Boot的一些核心註解,基於註解@Conditional元註解的組合註解就佔了很大部分,因此Spring Boot的核心功能基於就是這些註解實現的。在Spring Boot源碼項目「spring-boot-autoconfigure」中,隨意打開一個AutoConfiguration文件,咱們都會看到有上述條件註解的使用。如:

@Configuration
@ConditionalOnClass(DSLContext.class)
@ConditionalOnBean(DataSource.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class,
        TransactionAutoConfiguration.class })
public class JooqAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public DataSourceConnectionProvider dataSourceConnectionProvider(
            DataSource dataSource) {
        return new DataSourceConnectionProvider(
                new TransactionAwareDataSourceProxy(dataSource));
    }

    @Bean
    @ConditionalOnBean(PlatformTransactionManager.class)
    public SpringTransactionProvider transactionProvider(
            PlatformTransactionManager txManager) {
        return new SpringTransactionProvider(txManager);
    }
    ....
}

spring

 

 



Spring Boot運行原理

在前面的篇幅中咱們重點闡述了爲何Spring Boot能夠實現高度地自動化配置。那麼,接下來咱們就結合Spring Boot最核心的組合註解@SpringBootApplication來分析下Spring Boot的項目究竟是怎麼啓動運行的。

在這裏插入圖片描述

@SpringBootApplication註解其實是一個組合註解,除了對應用開放的@ComponentScan註解(實現對開發者自定義的應用包掃描)外,其最核心的註解就是註解@EnableAutoConfiguration,該註解表示開啓自動配置功能,而在具體的實現上則是經過導入註解@Import(EnableAutoConfigurationImportSelector.class)類的實例,在邏輯上實現了對所依賴的核心jar下META-INF/spring.factories文件的掃描,該文件則聲明瞭有哪些自動配置須要被Spring容器加載,從而Spring Boot應用程序就能自動加載Spring核心容器配置,以及其餘依賴的項目組件配置,從而最終完成應用的自動初始化,經過這種方法就向開發者屏蔽了啓動加載的過程。

如「spring-boot-autoconfigure」核心包中的META-INF/spring.factories文件就是定義了須要加載的Spring Boot項目所依賴的基礎配置類,如Spring的容器初始化配置類等。如:

# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer

.....

編程

 

 



而對於大部分第三方須要與Spring Boot集成的框架,或者咱們平常開發中須要進行抽象的公共組件而言,得益於這種機制,也能夠很容易地定製成開箱即用的各類Starter組件。而使用這些組件的用戶,每每只須要將依賴引入就好,再也不須要進行任何額外的配置了!
Spring Boot後記

以上就是Spring Boot運行的基本原理了,但願這篇文章可以對你有所幫助!實際上學習Spring Boot進行項目開發關鍵就是要掌握各類Spring及Spring Boot的各類註解,特別是一些關鍵核心註解。一樣在進行基於Spring Cloud微服務的開發中,也是須要理解Spring Cloud相關組件所提供的各類核心註解,只有這樣才能更好的理解框架的原理及使用,而不僅是雲裏霧裏地進行各類似懂非懂的Copy開發。


框架

相關文章
相關標籤/搜索