SpringBoot的自動配置原理

使用SpringBoot之後,一個整合了SpringMVC的WEB工程開發,變的無比簡單,那些繁雜的配置都消失不見了,這是如何做到的?

一切魔力的開始,都是從我們的main函數來的,所以我們再次來看下啟動類:

SpringBoot的自動配置原理

我們發現特別的地方有兩個:

  • 註解:@SpringBootApplication
  • run方法:SpringApplication.run()

我們分別來研究這兩個部分。

瞭解@SpringBootApplication

點擊進入,查看源碼:

SpringBoot的自動配置原理

這裡重點的註解有3個:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

4.1.1.@SpringBootConfiguration

SpringBoot的自動配置原理

通過這段我們可以看出,在這個註解上面,又有一個@Configuration註解。通過上面的註釋閱讀我們知道:這個註解的作用就是聲明當前類是一個配置類,然後Spring會自動掃描到添加了@Configuration的類,並且讀取其中的配置信息。而@SpringBootConfiguration是來聲明當前類是SpringBoot應用的配置類,項目中只能有一個。所以一般我們無需自己添加。

4.1.2.@EnableAutoConfiguration

關於這個註解,官網上有一段說明:

The second class-level annotation is @EnableAutoConfiguration. This annotation

tells Spring Boot to “guess” how you want to configure Spring, based on the jar

dependencies that you have added. Since spring-boot-starter-web added Tomcat

and Spring MVC, the auto-configuration assumes that you are developing a web

application and sets up Spring accordingly.

簡單翻譯以下:

第二級的註解@EnableAutoConfiguration,告訴SpringBoot基於你所添加的依賴,去“猜測”你想要如何配置Spring。比如我們引入了spring-boot-starter-web,而這個啟動器中幫我們添加了tomcat、SpringMVC的依賴。此時自動配置就知道你是要開發一個web應用,所以就幫你完成了web及SpringMVC的默認配置了!

總結,SpringBoot內部對大量的第三方庫或Spring內部庫進行了默認配置,這些配置是否生效,取決於我們是否引入了對應庫所需的依賴,如果有那麼默認配置就會生效。

所以,我們使用SpringBoot構建一個項目,只需要引入所需框架的依賴,配置就可以交給SpringBoot處理了。除非你不希望使用SpringBoot的默認配置,它也提供了自定義配置的入口。

4.1.3.@ComponentScan

我們進源碼

SpringBoot的自動配置原理

並沒有看到什麼特殊的地方。我們查看註釋:

SpringBoot的自動配置原理

大概的意思:

配置組件掃描的指令。提供了類似與<component-scan>標籤的作用/<component-scan>

通過basePackageClasses或者basePackages屬性來指定要掃描的包。如果沒有指定這些屬性,那麼將從聲明這個註解的類所在的包開始,掃描包及子包

而我們的@SpringBootApplication註解聲明的類就是main函數所在的啟動類,因此掃描的包是該類所在包及其子包。因此,一般啟動類會放在一個比較前的包目錄中。

默認配置原理:

4.2.1默認配置類

通過剛才的學習,我們知道@EnableAutoConfiguration會開啟SpringBoot的自動配置,並且根據你引入的依賴來生效對應的默認配置。那麼問題來了:

  • 這些默認配置是在哪裡定義的呢?
  • 為何依賴引入就會觸發配置呢?

其實在我們的項目中,已經引入了一個依賴:spring-boot-autoconfigure,其中定義了大量自動配置類:

SpringBoot的自動配置原理

還有

SpringBoot的自動配置原理

非常多,幾乎涵蓋了現在主流的開源框架,例如:

  • redis
  • jms
  • amqp
  • jdbc
  • jackson
  • mongodb
  • jpa
  • solr
SpringBoot的自動配置原理


  • elasticsearch

我們來看一個我們熟悉的,例如SpringMVC,查看mvc 的自動配置類:

打開WebMvcAutoConfiguration:

SpringBoot的自動配置原理

我們看到這個類上的4個註解:

  • @Configuration:聲明這個類是一個配置類
  • @ConditionalOnWebApplication(type = Type.SERVLET)
  • ConditionalOn,翻譯就是在某個條件下,此處就是滿足項目的類是是Type.SERVLET類型,也就是一個普通web工程,顯然我們就是
  • @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
  • 這裡的條件是OnClass,也就是滿足以下類存在:Servlet、DispatcherServlet、WebMvcConfigurer,其中Servlet只要引入了tomcat依賴自然會有,後兩個需要引入SpringMVC才會有。這裡就是判斷你是否引入了相關依賴,引入依賴後該條件成立,當前類的配置才會生效!
  • @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
  • 這個條件與上面不同,OnMissingBean,是說環境中沒有指定的Bean這個才生效。其實這就是自定義配置的入口,也就是說,如果我們自己配置了一個WebMVCConfigurationSupport的類,那麼這個默認配置就會失效!

接著,我們查看該類中定義了什麼:

視圖解析器

SpringBoot的自動配置原理

處理器適配器(HandlerAdapter)

SpringBoot的自動配置原理

還有很多,這裡就不一一截圖了。

4.2.2.默認配置屬性

另外,這些默認配置的屬性來自哪裡呢?

SpringBoot的自動配置原理

我們看到,這裡通過@EnableAutoConfiguration註解引入了兩個屬性:WebMvcProperties和ResourceProperties。這不正是SpringBoot的屬性注入玩法嘛。

我們查看這兩個屬性類:

SpringBoot的自動配置原理

找到了內部資源視圖解析器的prefix和suffix屬性。

ResourceProperties中主要定義了靜態資源(.js,.html,.css等)的路徑:

SpringBoot的自動配置原理

如果我們要覆蓋這些默認屬性,只需要在application.properties中定義與其前綴prefix和字段名一致的屬性即可。

4.3.總結

SpringBoot為我們提供了默認配置,而默認配置生效的條件一般有兩個:

  • 你引入了相關依賴
  • 你自己沒有配置

1)啟動器

所以,我們如果不想配置,只需要引入依賴即可,而依賴版本我們也不用操心,因為只要引入了SpringBoot提供的stater(啟動器),就會自動管理依賴及版本了。

因此,玩SpringBoot的第一件事情,就是找啟動器,SpringBoot提供了大量的默認啟動器,參考課前資料中提供的《SpringBoot啟動器.txt》

2)全局配置

另外,SpringBoot的默認配置,都會讀取默認屬性,而這些屬性可以通過自定義application.properties文件來進行覆蓋。這樣雖然使用的還是默認配置,但是配置中的值改成了我們自定義的。

因此,玩SpringBoot的第二件事情,就是通過application.properties來覆蓋默認屬性值,形成自定義配置。我們需要知道SpringBoot的默認屬性key,非常多,參考課前資料提供的:《SpringBoot全局屬性.md》


分享到:


相關文章: