本章內容html
摘錄:讀書是讀完這些文字還要好好用心去想一想,寫書也同樣,作任何事也同樣java
圖 2 第二章目錄結構圖react
Spring Boot 配置,包括自動配置和外化配置。本章先實現自定義屬性工程,將屬性外化配置在 application.properties 應用配置文件,而後在工程中獲取該屬性值。接着會詳細介紹屬性的獲取方式、外化配置和自動配置。最後會介紹利用自動配置自定義 Start 組件。git
第一章的 HelloBookController
控制層中,在代碼中以硬編碼的方式使用字符串表示書信息。下面把書的信息做爲屬性,外化配置在 application.properties 。好處是將應用參數、業務參數或第三方參數等統一配置在應用配置文件中,避免配置侵入業務代碼,達到可配置的方式,方便及時調整修改。github
新建工程命名爲 chapter-2-spring-boot-config ,在 application.properties 中配置書名和做者,配置以下:web
## 書信息 demo.book.name=[Spring Boot 2.x Core Action] demo.book.writer=BYSocket
.properties 文件的每行參數被存儲爲一對字符串,即一個存儲參數名稱,被稱爲鍵;另外一個爲值。通常稱爲鍵值對配置。井號(#)或者英文狀態下的歎號(!)做爲第一行中第一個非空字符來表示該行的文本爲註釋。另外,反斜槓()用於轉義字符。spring
Spring Boot 支持並推薦使用 YAML 格式的配置文件,將 application.properties 文件替換成 application.yml 文件,並配置相同的屬性,配置以下:shell
## 書信息 demo: book: name: 《Spring Boot 2.x 核心技術實戰 - 上 基礎篇》 writer: 泥瓦匠BYSocket
YAML 是一個可讀性高,用來表達數據序列的格式。表示鍵值對格式時,注意鍵和值由冒號及空白字符分開。強調下,空白字符是必須的,IDE 通常也會提示。兩種配置方式都很是便捷,在開發中選擇 .properties 或 .yml 文件配置。但若是兩種配置文件同時存在的時候,默認優先使用 .properties 配置文件。YAML 與 .properties 配置文件對好比圖 2-1 所示:數據庫
圖 2-1 YAML 與 .properties 配置文件對比數組
注意:
在 application.properties 配置中文值,讀取時會出現中文亂碼問題。由於 Java .properties 文件默認編碼方式是 iso-8859 ,Spring Boot 應用以 UTF-8 的編碼方式讀取,就致使出現亂碼問題。
官方 Issue 中的解決方法是,將 .properties 文件中配置的中文值轉義成 Unicode 編碼形式。例如 demo.book.writer=泥瓦匠
應該配置成 demo.book.writer=\u6ce5\u74e6\u5320
。利用 IDEA properties 插件 或利用 Java 文件轉碼工具 native2ascii 來快速地進行轉義。該工具備在線版實現,地址以下:
https://javawind.net/tools/na...
在工程中新建包目錄 demo.springboot.config
,並在目錄中建立名爲 BookProperties 的屬性類,代碼以下:
import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * 書屬性 */ @Component public class BookProperties { /** * 書名 */ @Value("${demo.book.name}") private String name; /** * 做者 */ @Value("${demo.book.writer}") private String writer; // ... 省略 getter / setter 方法 }
利用 @Component
註解定義了書的屬性 Bean,並經過 @Value
註解爲該 Bean 的成員變量(或者方法參數)自動注入 application.properties 文件的屬性值。@Value
註解是經過 「${propName}」 的形式引用屬性,propName 表示屬性名稱。
核心註解的知識點:
@Component
對類進行標註,職責是泛指組件 Bean ,應用啓動時會被容器加載並加入容器管理。常見的 @Controller
、@Service
、@Repository
是 @Component
的分類細化組件,分別對應控制層、服務層、持久層的 Bean。
@Value
對 Bean 的字段或者方法參數進行標註,職責是基於表達式給字段或方法參數設置默認屬性值。一般格式是註解 + SpEL 表達式,如 @Value("SpEL 表達式")
。
使用 @Vlaue
註解來引用屬性值時,確保所引用的屬性值在 application.properties 文件存在而且相對應匹配,不然會形成 Bean 的建立錯誤,引起 java.lang.IllegalArgumentException
非法參數異常。
修改原有的 HelloBookController
類,經過注入的方式獲取書屬性 Bean 並返回。代碼以下:
import demo.springboot.config.BookProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloBookController { @Autowired BookProperties bookProperties; @GetMapping("/book/hello") public String sayHello() { return "Hello, " + bookProperties.getWriter() + " is writing " + bookProperties.getName() + " !"; } }
經過 @Autowired
註解標記在 BookProperties
字段,控制層自動裝配屬性 Bean 並使用。默認狀況下要求被註解的 Bean 必須存在,須要容許 NULL 值,能夠設置其 required 屬性爲 false: @Autowired(required = false)
。
執行 ConfigApplication
類啓動,在控制檯看到成功運行的輸出後,打開瀏覽器訪問 /book/hello 地址,能夠看到如圖 2-2 所示的返回結果:
圖 2-2 Hello Book 頁面
也能夠經過單元測試的方式驗證屬性獲取是否成功,單元測試具體相關的會在第 9 章節介紹。單元測試代碼以下:
import demo.springboot.config.BookProperties; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class ConfigApplicationTests { @Autowired BookProperties bookProperties; @Test public void testBookProperties() { Assert.assertEquals(bookProperties.getName(),"'Spring Boot 2.x Core Action'"); Assert.assertEquals(bookProperties.getWriter(),"BYSocket"); } }
配置屬性的經常使用獲取方式有基於 @Value
和 @ConfigurationProperties
註解兩種方式。兩種方式適合的場景不一樣,下面具體介紹其使用方法和場景。
@Value
註解對 Bean 的變量或者方法參數進行標註,職責是基於表達式給字段或方法參數設置默認屬性值。一般格式是註解 + SpEL 表達式,如 @Value("SpEL 表達式")
,並標註在對應的字段或者方法上方,且必須對變量一一標註。這種方式適用於小而不復雜的屬性結構。屬性結構複雜,字段不少的狀況下,這種方式會比較繁瑣,應該考慮使用 @ConfigurationProperties
註解。
另外經過 @PropertySource
註解引入對應路徑的其餘 .properties 文件。將書信息從新配置在 classpath 下新的 book.properties 配置文件後,讀取新配置文件的代碼以下:
import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; /** * 書屬性 */ @Component @PropertySource("classpath:book.properties") public class BookProperties { /** * 書名 */ @Value("${demo.book.name}") private String name; /** * 做者 */ @Value("${demo.book.writer}") private String writer; // ... 省略 getters / setters 方法 }
在包目錄 demo.springboot.config
中建立名爲 BookComponent 的屬性類,並使用 @ConfigurationProperties
註解獲取屬性,代碼以下:
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * 書屬性 * */ @Component @ConfigurationProperties(prefix = "demo.book") public class BookComponent { /** * 書名 */ private String name; /** * 做者 */ private String writer; // ... 省略 getters / setters 方法 }
相似 @Value
註解方式,使用 @ConfigurationProperties(prefix = "demo.book")
註解標註在類上方能夠達到相同的效果。 @ConfigurationProperties
註解的 prefix 是指定屬性的參數名稱。會匹配到配置文件中 「 demo.book. 」 結構的屬性,星號 「 」 是指會一一對應匹配 BookComponent
類的字段名。例如,字段 name 表示書名,會匹配到 demo.book.name
屬性值。
@Value
註解方式強制字段必須對應在配置文件, @ConfigurationProperties
註解方式則不是必須的。通常狀況下,全部字段應該保證一一對應在配置文件。若是沒有屬性值對應的話,該字段默認爲空, @ConfigurationProperties
註解方式也不會引起任何異常,Spring Boot 推薦使用 @ConfigurationProperties
註解方式獲取屬性。
一樣使用單元測試驗證獲取屬性是否成功。單元測試代碼以下:
@Autowired BookComponent bookComponent; @Test public void testBookComponent() { Assert.assertEquals(bookComponent.getName(),"'Spring Boot 2.x Core Action'"); Assert.assertEquals(bookComponent.getWriter(),"BYSocket"); }
字符串值,綁定該名稱前綴的屬性對象。
字符串值,功能同 prefix 參數。
布爾值,默認 false。綁定對象時,忽略無效字段。
布爾值,默認 true。綁定對象時,忽略未知字段。
@ConfigurationProperties
註解方式支持驗證功能,即當屬性類被 @Validated
註解標註時,Spring Boot 初始化時會驗證類的字段。在類的字段上添加 JSR-303 約束註解,進行數據驗證。下面爲書屬性字段添加非 NULL 和字符串非空約束,代碼以下:
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; /** * 書屬性 * */ @Component @ConfigurationProperties(prefix = "demo.book") @Validated public class BookComponent { /** * 書名 */ @NotEmpty private String name; /** * 做者 */ @NotNull private String writer; // ... 省略 getters / setters 方法 }
經過 @Validated
註解開啓對 BookComponent
類字段的數據驗證,若是 name 字段爲 NULL 或者爲空字符串時,會引起 BindValidationException
綁定數據驗證異常。數據驗證經常使用在郵箱格式或者有長度限制的屬性字段。另外,驗證嵌套屬性的值,必須在嵌套對象字段上方標註 @Valid
註解,用來觸發其驗證。例如,在書屬性中新增嵌套對象出版社 Publishing
,就須要在該對象上方標註 @Valid
註解,來開啓對 Publishing
對象的數據驗證。綜上,兩種屬性獲取方式各有優缺點,對好比圖 2-3 所示:
圖 2-3 @ConfigurationPropertiesd vs @Value
Spring Boot 能夠將配置外部化,即分離存儲在 classpath 以外,這種模式叫作 「外化配置」。經常使用在不一樣環境中,將配置從代碼中分離外置,只要簡單地修改下外化配置,能夠依舊運行相同的應用代碼。外化配置表現形式不僅僅是 .properties 和 .yml 屬性文件,還可使用環境變量和命令行參數等來實現。那麼,多處配置了相同屬性時,Spring Boot 是經過什麼方式來控制外化配置的衝突呢?答案是外化配置優先級。
用命令行配置去覆蓋 .properties 文件配置方法很簡單。正常狀況下利用 Java 命令運行工程,代碼以下:
// chapter-2-spring-boot-config 目錄下運行 java -jar target/chapter-2-spring-boot-config-1.0.jar
下面將書的做者信息 BYSocket 改爲 Jeff , 經過命令行配置覆蓋屬性,代碼以下:
java -jar target/chapter-2-spring-boot-config-1.0.jar --demo.book.writer=Jeff
在命令行配置中,設置屬性值的格式是用兩個連續的減號 「--」標誌屬性。在控制檯看到成功運行的輸出後,打開瀏覽器,訪問 /book/hello 地址,能夠看到如圖 2-4 所示的返回結果:
圖 2-4 書信息被覆蓋頁面
經過命令行配置覆蓋屬性提供了很是大的做用與便利性,常見於使用 shell 腳本運行工程時,能夠方便地修改工程運行的配置。
可是這就引起了一個問題,豈不讓工程頗有侵入性,若是開放這個功能,致使未知的安全問題。因此 Spring Boot 提供了屏蔽命令行屬性值設置,在應用啓動類中設置 setAddCommandLineProperties
方法爲 false
,用於關閉命令行配置功能,代碼以下:
SpringApplication.setAddCommandLineProperties(false);
命令行配置屬性的優先級是第四。外化配置獲取屬性時,會按優先級從高到低獲取。若是高優先級存在屬性,則返回屬性,並忽略優先級低的屬性。優先級以下:
@TestPropertySource
註解配置@SpringBootTest
註解的 properties 配置ServletConfig
初始化參數配置ServletContext
初始化參數配置RandomValuePropertySource
配置@Configuration
類中的 @PropertySource 註解配置SpringApplication.setDefaultProperties
指定)在 application.properties 中配置屬性時,屬性之間能夠直接經過 「${propName}」 的形式引用其餘屬性。好比新增書的描述 description 屬性,代碼以下:
## 書信息 demo.book.name=[Spring Boot 2.x Core Action] demo.book.writer=BYSocket demo.book.description=${demo.book.writer}'s${demo.book.name}
demo.book.description 屬性引用了前面定義的 demo.book.name 和 demo.book.writer 屬性,其值爲 BYSocket's[Spring Boot 2.x Core Action] 。一方面可使相同配置能夠複用,另外一方面加強了配置的閱讀性。
在 application.properties 中配置屬性時,可使用隨機數配置,例如注入某些密鑰、UUID 或者測試用例,須要每次不是一個固定的值。RandomValuePropertySource
類隨機提供整形、長整形數、UUID 或者字符串。使用代碼以下:
my.secret=${random.value} my.number=${random.int} my.bignumber=${random.long} my.uuid=${random.uuid} my.number.less.than.ten=${random.int(10)} my.number.in.range=${random.int[1024,65536]}
多環境是指不一樣配置的生產服務器使用同一工程代碼部署,好比:開發環境、測試環境、預發環境、生產環境等。各個環境的工程端口、數據庫配置、Redis 配置、日誌配置等都會不一樣,傳統模式下須要修改配置,工程從新編譯打包,並部署到指定環境服務器。結果是容易發生配置錯誤,致使開發部署效率低下。Spring Boot 使用多環境配置去解決這個問題。
多環境配置,相似 Maven 構建配置文件的思路,即配置多個不一樣環境的配置文件,再經過 spring.profiles.active
命令去指定讀取特定配置文件的屬性。多環境配置文件是不一樣於 application.properties 應用配置文件。多環境配置文件的約定命名格式爲 application-{profile}.properties。多環境配置功能默認爲激活狀態,若是其餘配置未被激活,則 {profile} 默認爲 default,會加載 application-default.properties 默認配置文件,沒有該文件就會加載 application.properties 應用配置文件。
多環境配置文件的屬性讀取方式和從 application.properties 應用配置文件讀取方式一致。無論多環境配置文件在工程 jar 包內仍是包外,按照配置優先級覆蓋其餘配置文件。在微服務實踐開發中,常常會使用一個相似 deploy 工程去管理配置文件和打包其餘業務工程。
在 application.properties 同級目錄中,新建 application-dev.properties 做爲開發環境配置文件,配置以下:
## 書信息 demo.book.name=[Spring Boot 2.x Core Action] From Dev demo.book.writer=BYSocket
新建 application-prod.properties 做爲生產環境配置文件,代碼以下:
## 書信息 demo.book.name=<Spring Boot 2.x Core Action Dev> From Prod demo.book.writer=BYSocket
經過命令行指定讀取 dev 環境配置文件並運行工程,代碼以下:
java -jar target/chapter-2-spring-boot-config-1.0.jar --spring.profiles.active=dev
在多個環境配置中,經過命令 --spring.profiles.active=dev
指定讀取某個配置文件,將 dev 更改爲 prod ,輕鬆切換讀取生產環境配置。也能夠在控制檯的日誌中肯定配置讀取來自 dev :
2017-11-09 12:10:52.978 INFO 72450 --- [ main] demo.springboot.ConfigApplication : The following profiles are active: dev
最後打開瀏覽器,訪問 /book/hello 地址,能夠看到如圖 2-5 所示的返回結果:
圖 2-5 dev 環境書信息頁面
Spring Boot spring-boot-autoconfigure
依賴實現了默認的配置項,即應用默認值。這種模式叫作 「自動配置」。Spring Boot 自動配置會根據添加的依賴,自動加載依賴相關的配置屬性並啓動依賴。例如默認用的內嵌式容器是 Tomcat ,端口默認設置爲 8080。
爲何須要自動配置?顧名思義,自動配置的意義是利用這種模式代替了配置 XML 繁瑣模式。之前使用 Spring MVC ,須要進行配置組件掃描、調度器、視圖解析器等,使用 Spring Boot 自動配置後,只須要添加 MVC 組件便可自動配置所須要的 Bean。全部自動配置的實現都在 spring-boot-autoconfigure
依賴中,包括 Spring MVC 、Data 和其它框架的自動配置。
spring-boot-autoconfigure
依賴,是 Spring Boot 實現自動配置的核心 Starter 組件。其實現源碼包結構如圖 2-6 所示:
圖 2-6 spring-boot-autoconfigure 依賴包目錄
從圖中能夠看出,其中常見核心的包以下:
org.springframework.boot.autoconfigure org.springframework.boot.autoconfigure.data.jpa org.springframework.boot.autoconfigure.thymeleaf org.springframework.boot.autoconfigure.web.servlet org.springframework.boot.autoconfigure.web.reactive ... 省略
在各自包目錄下有對應的自動配置類,代碼以下:
JpaRepositoriesAutoConfiguration ThymeleafAutoConfiguration WebMvcAutoConfiguration WebFluxAutoConfiguration ... 省略
上面自動配置類依次是 Jpa 自動配置類、Thymeleaf 自動配置類、Web MVC 自動配置類和 WebFlux 自動配置類。WebFlux 響應式框架會在第 3 章 詳細介紹使用。
spring-boot-autoconfigure
職責是經過 @EnableAutoConfiguration
核心註解,掃描 ClassPath 目錄中自動配置類對應依賴,並按必定規則獲取默認配置並自動初始化所須要的 Bean。在 application.properties 配置文件也能夠修改默認配置項,經常使用配置清單地址以下:
https://docs.spring.io/spring...
自動配置工做機制是經過 @EnableAutoConfiguration
註解中 @Import
的 AutoConfigurationImportSelector
自動配置導入選擇器類實現的。查閱源碼可得具體流程以下:
AutoConfigurationImportSelector
經過 SpringFactoriesLoader.loadFactoryNames()
核心方法讀取 ClassPath 目錄下面的 META-INF/spring.factories 文件。WebMvcAutoConfiguration
Web MVC 自動配置類和ServletWebServerFactoryAutoConfiguration
容器自動配置類 。例如添加 spring-boot-starter-web
依賴後,啓動應用會觸發容器自動配置類。容器自動配置類 ServletWebServerFactoryAutoConfiguration
的部分代碼以下:
package org.springframework.boot.autoconfigure.web.servlet; @Configuration @ConditionalOnClass({ServletRequest.class}) @ConditionalOnWebApplication( type = Type.SERVLET ) @EnableConfigurationProperties({ServerProperties.class}) @Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class}) public class ServletWebServerFactoryAutoConfiguration { ... 省略 }
上面代碼中,@ConditionalOnClass
註解表示對應的 ServletRequest
類在 ClassPath 目錄下面存在,而且 @ConditionalOnWebApplication
註解表示該應用是 Servlet Web 應用時,纔會去啓動容器自動配置,並經過 ServerProperties 類默認設置了端口爲 8080。Type.SERVLET 枚舉表明 Servlet Web 應用,Type.REACTIVE 枚舉表明響應式 WebFlux 應用。
自動配置,是一把雙刃劍。用好了就像天下武功惟快不破同樣。但要注意一些自動化配置形成的問題。常見的問題有:
相似場景下,解決方式是經過 exclude 屬性指定並排除自動配置類,代碼以下:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
也等價於配置 @EnableAutoConfiguration
註解,代碼以下:
@SpringBootApplication @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
自動配置會最大的智能化,只有配置了 exclude 屬性時,Spring Boot 優先初始化用戶定義的 Bean ,而後再進行自動配置。
當公司須要共享或者開源 Spring Boot Starter 組件依賴包,就能夠利用自動配置自定義 Starter 組件。一個完整的 Starter 組件包括如下兩點:
實現自定義 Starter 組件,並不會將這兩點嚴格區分,能夠將自動配置功能和依賴管理結合在一塊兒實現。下面利用自動配置實現自定義 Starter 組件:spring-boot-starter-swagger 組件是用來快速生成 API 文檔,簡化原生使用 Swagger2 。
spring-boot-starter-swagger 組件爲 Spring For All 社區(spring4all.com)開源項目,源代碼地址是 https://github.com/SpringForA...。
Swagger2 是 API 最大的開發框架,基於 OpenAPI 規範(OAS),管理了 API 整個生命週期,即從 API 設計到文檔,從測試到部署。具體更多瞭解見其官網,https://swagger.io。
建立一個新的 Spring Boot 工程,命名爲 spring-boot-starter-swagger。在 pom.xml 配置相關
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${version.swagger}</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${version.swagger}</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-bean-validators</artifactId> <version>${version.swagger}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.12</version> <scope>provided</scope> </dependency> </dependencies>
配置中添加了 spring-boot-starter
組件依賴用於自動配置特性,springfox-swagger2
依賴是 Swagger2 框架。
新建名爲 SwaggerProperties
Swagger2 屬性配置類,包含了全部默認屬性值。使用該組件時,能夠在 application.properties 配置文件配置對應屬性項,進行覆蓋默認配置。代碼以下:
import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.boot.context.properties.ConfigurationProperties; import springfox.documentation.schema.ModelRef; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @Data @ConfigurationProperties("swagger") public class SwaggerProperties { /**是否開啓swagger**/ private Boolean enabled; /**標題**/ private String title = ""; /**描述**/ private String description = ""; /**版本**/ private String version = ""; /**許可證**/ private String license = ""; /**許可證URL**/ private String licenseUrl = ""; /**服務條款URL**/ private String termsOfServiceUrl = ""; private Contact contact = new Contact(); /**swagger會解析的包路徑**/ private String basePackage = ""; /**swagger會解析的url規則**/ private List<String> basePath = new ArrayList<>(); /**在basePath基礎上須要排除的url規則**/ private List<String> excludePath = new ArrayList<>(); /**分組文檔**/ private Map<String, DocketInfo> docket = new LinkedHashMap<>(); /**host信息**/ private String host = ""; /**全局參數配置**/ private List<GlobalOperationParameter> globalOperationParameters; ... 省略,具體代碼見 GitHub }
用 @ConfigurationProperties(prefix = "swagger")
標註在類上方是指定屬性的參數名稱爲 swagger。會對應匹配到配置文件中 「 swagger.* 」 結構的屬性,例如,字段標題 title 表示標題,會匹配到 swagger.title
屬性值。
新建名爲 SwaggerAutoConfiguration
Swagger2 自動配置類,提供 Swagger2 依賴關係管理功能和自動配置功能。代碼以下:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @Configuration @ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true) @Import({ Swagger2DocumentationConfiguration.class, BeanValidatorPluginsConfiguration.class }) public class SwaggerAutoConfiguration implements BeanFactoryAware { private BeanFactory beanFactory; @Bean @ConditionalOnMissingBean public SwaggerProperties swaggerProperties() { return new SwaggerProperties(); } @Bean @ConditionalOnMissingBean @ConditionalOnProperty(name = "swagger.enabled", matchIfMissing = true) public List<Docket> createRestApi(SwaggerProperties swaggerProperties) { ... 省略,具體代碼見 GitHub } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } }
上面代碼實現流程以下:
@Configuration
註解標註在類上方,代表該類爲配置類。@Import
註解引入 Swagger2 提供的配置類 Swagger2DocumentationConfiguration
和 Bean 數據驗證插件配置類 BeanValidatorPluginsConfiguration
。@ConditionalOnMissingBean
註解標註了兩處方法,當 Bean 沒有被建立時會執行被標註的初始化方法。第一處被標記方法是 swaggerProperties()
,用來實例化屬性配置類 SwaggerProperties
;第二處被標記方法是 createRestApi()
, 用來實例化 Swagger2 API 映射的 Docket 列表對象。@ConditionalOnProperty
註解標註在 createRestApi()
方法,name 屬性會去檢查環境配置項 swagger.enabled
。默認狀況下,屬性存在且不是 false
的狀況下,會觸發該初始化方法。matchIfMissing 屬性默認值爲 false
,這裏設置爲 true
,表示若是環境配置項沒被設置,也會觸發。新建名爲 EnableSwagger2Doc
Swagger2 啓動註解類,用於開關 spring-boot-starter-swagger 組件依賴。代碼以下:
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Import({SwaggerAutoConfiguration.class}) public @interface EnableSwagger2Doc { }
上面代碼 @Import
註解引入 Swagger2 自動配置類 SwaggerAutoConfiguration
。當將該註解配置在應用啓動類上方,便可開啓 Swagger2 自動配置及其功能。
上面簡單介紹了spring-boot-starter-swagger 組件的核心代碼實現,一樣使用方式也很簡單。在 chapter-2-spring-boot-config 工程的 Maven 配置中添加對應的依賴配置,目前支持 1.5.0.RELEASE 以上版本,配置以下:
<!-- 自定義 swagger2 Starter 組件依賴 --> <dependency> <groupId>com.spring4all</groupId> <artifactId>spring-boot-starter-swagger</artifactId> <version>2.0</version> </dependency>
另外,須要在 ConfigApplication 應用啓動類上方配置啓動註解類 EnableSwagger2Doc
,代碼以下:
import com.spring4all.swagger.EnableSwagger2Doc; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @EnableSwagger2Doc // 開啓 Swagger @SpringBootApplication public class ConfigApplication { public static void main(String[] args) { SpringApplication.run(ConfigApplication.class, args); } }
執行 ConfigApplication
類啓動,在控制檯看到成功運行的輸出後,打開瀏覽器訪問 localhost:8080/swagger-ui.html 地址,能夠看到自動生成的 Swagger API 文檔,如圖 2-7 所示:
圖 2-7 Swagger API 文檔
Class 數組,排除特定的自動配置類。
字符串數組,排除特定名稱的自動配置類。
字符串,屬性指望值是否匹配。
布爾值,若是該屬性值未設置,則匹配。
字符串數組,要測試的屬性名。
字符串,屬性前綴名。
字符串,功能同 name。
字符串數組,類名必須存在。
Class 數組,類必須存在。
註解 Class 數組,匹配註解裝飾的 Bean。
字符串數組,匹配時,忽略該類型名稱的 Bean。
字符串數組,匹配要檢查的 Bean 名稱。
SearchStrategy 對象,經過 SearchStrategy 來決定程序的上下文策略。
字符串史胡族,匹配要檢查的 Bean 類型名稱。
Class 數組,匹配要檢查的 Bean 類型。
ConditionalOnWebApplication.Type 對象,匹配對應的 Web 應用程序類型。
本章從自定義屬性快速入門工程出發,介紹了兩種配置文件以及屬性的獲取方式,而後講解了外化配置的優先級、屬性引用、隨機式使用和多環境配置,最後講解了自動配置的原理、核心註解以及利用自動配置實現了自定義 Starter 組件。下一章介紹 Spring Boot Web 開發相關。
本章示例代碼地址:https://github.com/JeffLi1993...
本文由博客羣發一文多發等運營工具平臺 OpenWrite 發佈