2.Spring Boot核心

2.1 基本配置
1.入口類和@SpringBootApplication
Spring boot通常有一個名爲*Application的入口類,入口類裏面有一個main方法,這個main方法其實就是一個標準的java應用的入口方法。在main方法中使用SpringApplication.run(StudydemoApplication.class, args),啓動spring boot應用項目。
@SpringBootApplication是Spring boot的核心註解,它是一個組合註解,組合了@Configuration、@EnableAutoConfiguration、@ComponmentScan。其中@EnableAutoConfiguration是讓spring boot根據類路徑中的jar包依賴爲當前項目進行自動配置。
例如,添加了spring-boot-starter-web依賴,會自動添加tomcat和springmvc的依賴,那麼spring boot會對tomcat和springmvc進行自動配置。
又如,添加了spring-boot-starter-data-jpa依賴,spring boot會自動進行JPA相關的配置。
Spring boot會自動掃描@SpringBootApplication所在類的同級包以及下級包裏面的bean。建議入口類放置的位置在groupid+arctifactid組合的包名下。
如:
這裏寫圖片描述

2.關閉特定的自動配置應該使用@SpringBootApplication註解的exclude參數
如:@SpringBootApplication(exclude={DataSourceAutoConfiguration.class}).

3.Spring Boot的配置文件
Spring boot使用一個全局的配置文件application.properties或application.yml,放置在src/main/resources目錄或者類路徑的/config下。
Spring boot的全局配置文件的作用是對一些默認配置的配置值進行修改,
比如修改tomcat默認的端口號8080修改爲9090,並將默認的訪問路徑「/」修改爲「/helloboot」。可以在application.properties裏面添加如下圖:

這裏寫圖片描述

4.Starter pom
Spring boot爲我們提供了簡化企業級開發絕大多數場景的starter pom,只要使用了應用場景所需要的starter pom,相關的技術配置將會消除,就可以得到spring boot爲我們提供的自己配置的Bean。可登陸官網查看,除了官方的starter pom外,還有第三方爲spring boot所寫的starter pom。

5.使用xml配置
Spring boot提倡零配置,即無xml配置,但是在實際項目中,可能有一些特殊要求你必須使用xml配置,這時我們可以通過spring提供的@ImportResources來加載xml配置,例如:
@ImportResources(「classpath:a.xml」,「classpath:b.xml」)

2.2 外部配置
1.常規屬性配置
在spring boot裏,我們只需在application.properties定義屬性,然後直接使用@Value注入即可。如下圖:

這裏寫圖片描述

這裏寫圖片描述

2.類型安全的配置(基於properties)
Spring boot還提供了基於類型安全的配置方法,通過@ConfigurationProperties將properties屬性和一個Bean及其屬性關聯,從而實現類型安全的配置。Application.properties的配置如下圖:
這裏寫圖片描述
類型安全的bean,如下圖:
這裏寫圖片描述

通過@ConfigurationProperties加載properties文件內的配置,通過prefix屬性指定properties的配置的前綴,也可以通過locations指定properties文件的位置。

執行代碼如下:
這裏寫圖片描述

效果如下圖:
這裏寫圖片描述
2.3 日誌配置
Spring boot支持Java Util Logging、Log4j、Log4j2和Logback作爲日誌框架,無論使用哪種日誌框架,spring boot已爲當前使用日誌框架的控制檯輸出以及文件輸出做好了配置。
默認情況下,spring boot使用logback作爲日誌框架。
配置日誌文件:logging.file=D:/bootlog/log.log, 配置日誌的級別,格式爲logging.level.包名=級別:logging.level.com.springboot.studydemo=DEBUG

2.4 Profile配置
Profile是spring用來針對不同的環境提供不同的配置,全局的profile配置使用application-{profile}.properties(如application-prod.properties)。通過在application.properties中設置spring.profie.active=prod來指定活動的Profile。

2.5 Spring Boot運行原理
Spring 4.x提供了基於條件來配置Bean的能力,其實spring boot神奇的實現也是基於這一原理。
Spring boot關於自動配置的源碼在spring-boot-autoconfigure-xxx.jar內,可以通過下面三種方式查看當前項目中已啓動和未啓動的自動配置的報告。
(1).運行jar時增加–debug參數
Java -jar xx.jar –debug
(2).在application.properties中設置屬性
Debug=true
(3).這裏寫圖片描述

在控制檯輸出,已啓動的自動配置爲:
這裏寫圖片描述
未啓動的自動配置爲:

這裏寫圖片描述

1.運作原理
關於spring boot的運作原理,還是迴歸到@SpringBootApplication註解上來,它是一個組合註解,它的核心功能是由@EnableAutoConfiguration註解提供的。源碼如下:
這裏寫圖片描述
這裏的關鍵功能是@Import註解導入的配置功能,EnableAutoConfigurationImportSelector使用SpringFactoriesLoader.loadFactoryNames方法來掃描具有META-INF/spring.factories文件的jar包,而spring-boot-autoconfigure-xx.jar就有一個spring.factories文件。如下:
這裏寫圖片描述
2.核心註解
打開上面任意一個AutoConfiguration文件,一般都有下面的條件註解,在spring-boot-autoconfigure-xx.jar的org.springframwork.boot.autoconfigure.condition包下,條件註解如下:

@ConditionalOnBean: 當容器裏有指定的bean的條件下
@ConditionalOnClass: 當類路徑下有指定的類的條件下
@ConditionalOnExpression: 基於SpEL表達式作爲判斷條件
@ConditionalOnJava: 基於jvm版本作爲判斷條件
@ConditionalOnJndi: 在JNDI存在的條件下查找指定的位置
@ConditionalOnMissingBean: 在容器裏沒有指定bean的情況下
@ConditionalOnMissingClass: 當類路徑下沒有指定的類的條件下
@ConditionalOnNotWebApplication: 當前項目不是Web項目的條件下
@ConditionalOnProperty: 指定的屬性是否有指定的值
@ConditionalOnResources: 類路徑是否有指定的值
@ConditionalOnSingleCandidate: 當指定Bean在容器裏只有一個,或者雖然有多個但是指定首選的bean
@ConditionalOnWebApplication:當前項目是web項目的條件下

這些註解都組合了@Conditional元註解,只是使用了不同的條件。

3.自定義starter pom
我們自定義一個starter pom,這意味着我們不僅有自動配置的功能,而且具有更通用的耦合度更低的配置。
下面建一個例子:當包中存在某個類的時候,自動配置這個類的Bean,並可在application.properties中配置Bean的屬性值。

(1).新建一個maven項目,目錄結構如下:
這裏寫圖片描述
(2).pom引入以下依賴:
這裏寫圖片描述
(3).新建屬性配置的類:
這裏寫圖片描述
(4).新建判斷依據類

這裏寫圖片描述
本例子是根據此類的存在與否來創建這個類的Bean

(5).新建自動配置類:
這裏寫圖片描述
代碼說明
1. @Configuration:使用該註解來說明該類是配置類,等價於xml中的beans
2. @EnableConfigurationProperties(HelloServiceProperties.class):開啓屬性注入,對註解配置Bean的支持
3. @ConditionalOnClass(HelloService.class):條件註解,當類路徑下有指定的類的條件下。
4. @ConditionalOnProperty(prefix=」hello」,value=」enabled」,matchIfMissing=true):條件註解,指定的屬性是否有指定的值。當設置hello=enabled,如果沒有設置則默認爲true,即爲條件符合。假如我們將matchIfMissing設置爲false,則當設置hello=enabled時,條件爲false,則不會將該Bean加載進容器類,當使用@Autowired注入HelloService時會報錯。
TODO:我項目中即使配了@ConditionalOnProperty(prefix=」hello」,value=」enabled」,matchIfMissing=true),也會報錯,沒找到原因,求大神賜教,所以貼圖上沒有此註解。
[email protected]:使用Java配置的方式來配置這個類,等價於xml中的bean。
[email protected](HelloService.class):容器中沒有這個Bean時,新建這個Bean。
(6).註冊配置
若想自動配置生效,需要註冊自動配置類。在src/main/resources下新建META-INF/spring.factories,結構如下:
這裏寫圖片描述
在spring.factories中註冊:
這裏寫圖片描述
如有多個自動配置,則用」,」隔開,此處的」\」是爲了換行後仍然能讀到屬性。

最後執行mvn -install 把jar安裝到本地倉庫。

下面在之前的項目中引入依賴:
這裏寫圖片描述

簡單的運行類代碼如下:
這裏寫圖片描述

在代碼中可以直接注入HelloService的Bean,但是在項目中我們並沒有配置這個Bean,這是通過自動配置完成的。

運行結果:

這裏寫圖片描述
這是在application.properties中設置hello.msg= dota
再次運行:
這裏寫圖片描述

新增的自動配置顯示在控制檯的報告中,如下圖:
這裏寫圖片描述