

什么是springboot
在學springboot之前,你必須有spring、spring mvc基礎,springboot的誕生其實就是用來簡化新Spring應用的初始搭建以及開發過程,該框架使用了特定的方式來進行配置,從而使開發人員不再需要定義樣板化的配置。
它集成了大量常用的第三方庫配置(例如JDBC, Mongodb, Redis, Mail,rabbitmq等等),所以在Spring Boot應用中這些第三方庫幾乎可以零配置的開箱即用(out-of-the-box),大部分的Spring Boot應用都只需要非常少量的配置代碼,開發者能夠更加專注於業務邏輯。
也就是說,以前集成ssm框架需要一大堆的xml配置文件,效率底下,而使用了springboot之后,很多時候我們不需要寫任何配置了,有時候直接通過@EnableXXX就能開啟某個模塊的功能。
現在問題來了,你知道@EnableXXX是什么原理嗎?
mvc、boot、cloud
這里直接引用網友的總結給大家介紹一下:
Spring 是一個“引擎”;springmvc是框架,web項目中實際運行的代碼;spring boot只是一個配置工具,整合工具,輔助工具,是一套快速開發整合包。
Spring Boot :J2EE一站式解決方案 Spring Cloud :分布式整體解決方案
約定大於配置的體現
在於減少軟件開發人員所需要做出的決定的數量,從而獲得簡單的好處,而又不失去其中的靈活性。
1、Spring Boot默認提供靜態資源目錄位置需置於classpath下,目錄名需符合如下規則:/static /public /resources /META-INF/resources 優先級:META/resources > resources > static > public

2、spring boot默認的配置文件必須是,也只能是application或application-xxx命名的yml文件或者properties文件,我推薦盡量使用yml文件~
3、application.yml中默認屬性:a、數據庫連接信息必須是以spring: datasource: 為前綴,如:

b、多環境配置。該屬性可以根據運行環境自動讀取不同的配置文件。例如將該屬性定義為dev的話,Spring Boot會額外從 application-dev.yml 文件中讀取該環境的配置。

c、修改端口號、請求路徑

4、starter啟動器,開箱即用的Starter依賴讓springboot可以實現零配置即可自動完成框架的整合。
-
spring-boot-starter-web
-
嵌入tomcat和web開發需要servlet與jsp支持
-
spring-boot-starter-data-jpa
-
數據庫支持
-
spring-boot-starter-data-redis
-
redis數據庫支持
-
spring-boot-starter-data-solr
-
solr支持
-
mybatis-spring-boot-starter
-
第三方的mybatis集成starter
接下來我們來分析一下springboot注入bean有多少種方式。
手動裝配
在學習springboot中,我喜歡把總結springboot的一些特性,以及使用springboot的一些規律,比如:在springboot加載bean的過程我分為了
-
手動裝配
-
自動裝配
兩種方式,而手動裝配又分為了
-
模式注解裝配
-
@Enable模塊裝配
-
條件裝配
3種方式,接下來我們來一一探討每種。
首先來看下手動裝配:
1、模式注解裝配
其實就是使用@Component注解,或者@Component注解的拓展,比如@Controller、@Service、Repository、@Configruation等,
這也是我們最常用的一種方式,直接通過spring mvc的注解把組件bean注入到spring容器中。
2、@Enable模塊裝配
-
基於接口驅動實現
當我們需要開啟springboot項目的緩存功能時候,我們直接打開@EnableCaching注解就可以注入Caching 模塊,這時候我們就可以開心使用@Cacheable、@CacheEvict等注解,這是怎么做到的?
其實你打開@EnableCaching的源碼你就能看到:

上面最重要的一句代碼就是@Import({CachingConfigurationSelector.class}),你會發現,其實使用@EnableCaching,就是為了導入CachingConfigurationSelector.class這配置類。
而這個CachingConfigurationSelector,其實實現了ImportSelector接口,ImportSelector接口是spring中導入外部配置的核心接口,只有一個方法selectImports,其實就是根據EnableCaching的元數據屬性(proxyTargetClass、mode、order),選擇出需要轉配的Configuration。

總結其實是這樣子,@EnableCaching其實就是根據元數據屬性然后選擇性條件判斷注入需要的配置,比較靈活。
-
基於注解驅動實現
然后我們來看另一種沒有元數據屬性的@EnableWebMvc。

可以很直觀看到,其實@EnableWebMvc其實就是為了導入DelegatingWebMvcConfiguration配置類,某種程度上,可以認為@EnableWebMvc其實和@Import({DelegatingWebMvcConfiguration.class})是對等的,只是起了一個有意義的名字而已。
所以我們總結一下@EnableXXX模塊注入,基於接口驅動實現是實現ImportSelector接口,通過注解參數選擇需要導入的配置,而基於注解驅動實現其實就是@Import的派生注解,直接導入某個配置類。
思維導圖總結如下:

3、條件裝配
所謂條件裝配,其實是Bean裝配的前置條件,我們先來看一下例子:
-
@ConditionalOnBean
-
僅僅在當前上下文中存在某個對象時,才會實例化一個Bean
-
@ConditionalOnExpression
-
當表達式為true的時候,才會實例化一個Bean
-
@ConditionalOnMissingClass
-
某個class類路徑上不存在的時候,才會實例化一個Bean
-
@ConditionalOnNotWebApplication
-
不是web應用
這就是條件裝配,當這些條件注解放在某個bean上面的時候,只有滿足了條件才能注入bean,這也是為什么springboot能這么智能,知道哪些模塊需要開啟,哪些不需要,比如當你導入Freemaker的jar包之后,就自動幫你加載Freemaker的的相關配置,其實你看下代碼:

這些springboot的自動配置類上面一般是不是都有@ConditionalOnClass注解,這里是說當發現項目有freemarker.template.Configuration.class, FreeMarkerConfigurationFactory.class這兩個Class存在時候,我就加載這個FreeMarkerAutoConfiguration,什么時候才會存在這兩個Class?當我們導入jar包時候:

所以,當我們沒有導入相關jar包時候,我們不用擔心springboot會自動開啟某些功能,而是會智能判斷哪些需要開啟,哪些需要跳過。
我們打開@ConditionalOnClass的源碼,發現其實是@Conditional拓展出來的注解。

實現邏輯如下:OnClassCondition.class實現Condition接口,並實現matches()方法,如果matches方法返回true,那么帶有@Conditional注解的bean就會裝載,false就不會裝載。
思維導圖總結如下:

自動裝配
ok,剛才我們已經說了很多關於手動裝配部分的東西,現在我們來看下自動裝配,其實很多時候自動裝配就是手動裝配的綜合運用,只不過在轉配bean或配置類時候,我們不在需要使用@EnableXXX來導入功能,而是通過自動注入方式。
這時候自動注入的條件判斷(@Conditional)就顯得非常重要了。
我們再用剛才說的Freemaker作為例子,springboot集成freemaker非常簡單,只需要導入starter的jar包就會自動實現注入,這個自動集成就是FreeMarkerAutoConfiguration這里配置的。
這里有個問題,你知道為什么springboot會自動去判斷和加載FreeMarkerAutoConfiguration這個配置類嗎?我沒有寫類似的@EnableFreemaker,那項目怎么識別的。
其實如果你看過springboot的源碼,你就會發現:

上面的意思是去掃描項目下所有的META-INF/spring.factories文件,然后把EnableAutoConfiguration.class作為key找出對應的值,這個值是個List。那么我們來看下其中一個spring.factories長什么樣子的。
-
spring-boot-autoconfigure/2.1.2.RELEASE/spring-boot-autoconfigure-2.1.2.RELEASE.jar!/META-INF/spring.factories
可以看到EnableAutoConfiguration作為key有很多個值,比如RabbitMq的自動配置類等,而你認證點看,就能找到FreeMarkerAutoConfiguration這配置類了。
所以情況是這個的,當springboot項目啟動時候,項目會去加載所有的spring.factories文件,然后在EnableAutoConfiguration后面的所有配置類其實都是可以實現自動裝配的配置,至於需不需要裝配,就需要條件裝配來判定是否滿足特定的條件了。
有了這點基礎之后,我們就可以自己去寫自動裝配了。
第一步、編寫需要自動裝載的配置類。
說明:@Configuration表示是個配置類 @ConditionalOnSystemProperty表示需要滿足當前系統是win10系統

- 第二步、在resources目錄下新建META-INF文件夾,編寫spring.factories。

-
啟動springboot之后就會自動加載這個配置類,於是,我們就注入了SayHelloWorld這個業務bean,項目中就可以直接注入使用啦~
有人說,這和直接寫個@Configruation有啥區別,區別在於@Configruation的配置必須寫在Spring能掃描到的目錄下,而自動裝配不需要。
思維導圖總結如下:

好了,今天的內容先到這里了哈,后面我們會去用詳細分析和代碼實現@EnableXXX,還有自動裝配,手寫starter等。
