最近在學習了 Spring Boot
後,也用它寫了一個簡單的項目,真的發現它對使用 Spring
開發的人來講是一大福音,無需在像之前那樣須要配置不少東西。這篇文章,就結合一些常見的面試題和開發中會用到的,對 Spring Boot
來總結一下。html
Spring Boot
,看這個名字,就能夠猜出來它是一個快速啓動 Spring
的框架,其實也正是如此,它採用「約定大於配置」的理念,提供了大量的自動配置,而無須再去編寫模板化的配置文件,能夠快速地建立一個能夠獨立運行的 Spring
項目。java
除了自動配置特性以外,它還有如下特性:web
starter 啓動器面試
它提供了不少框架的 starter
啓動器,來簡化 maven
的依賴管理。Spring
項目中,在導入其餘框架的依賴時,還須要導入其餘附屬的依賴,若是框架比較多,那就會比較難以管理。而 Spring Boot
中提供了各類 starter
啓動器,能夠對其進行很好的管理。例如,導入 spring-boot-starter-web
依賴後,會自動添加以下依賴:spring
內嵌 Servlet 容器bash
它內嵌了不少 Servlet
容器,能夠選擇 Tomcat
、Jetty
等。這樣就無須先下載 Tomcat
,搭建好運行環境,再以 war
包的形式進行部署,而是能夠直接以 jar
包的形式,經過 java -jar xxx.jar
去獨立運行。架構
準生產環境的應用監控app
提供了準生產環境的應用監控。能夠基於 HTTP
、JMX
、SSH
等對運行時的項目進行監控。對 Actuator
還不太瞭解,後續再進行補充。框架
不少人應該都據說過這三個東西,那它們之間到底有什麼區別呢?dom
學過 Spring
的應該都知道這樣一句話,Spring
是一個 JavaSE/EE
一站式的輕量級開源框架。其中提供了不少模塊,例如 IoC
、AOP
、MVC
、Test
等。SpringMVC
只是其中的一個模塊。
而 SpringBoot
是基於 Spring
的一個 Boot
啓動器,爲了更容易、更快速地搭建一個 Spring
項目。針對的是單體應用。
SpringCloud
則是微服務架構下的一個綜合性解決方案,對使用 SpringBoot
開發的一個個服務進行管理,它整合了許多基礎組件,來解決業務拆分後帶來的如配置管理、服務治理、容錯等問題。
Spring Boot 的啓動方式主要有三種,下面就分別來看一下:
1. 打成 jar 包
前面說了 Spring Boot
中內置了 Serlvet
容器,能夠直接使用 java -jar xxx.jar
。目前也推薦使用這種方式。另外經過這種方式,也能夠在運行時指定一些參數。
在 pom.xml
文件中,引入 spring-boot-maven-plugin
插件後:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
複製代碼
能夠執行 mvn clean package
命令,將其打包成一個 jar
包,而後就能夠經過 jar -jar xxx.jar
命令運行。
2. 運行 main 方法
在 Spring Boot
項目都會有一個主類,能夠經過運行該類的 main
方法來啓動。這比較適用於開發調試的時候。
3. 打成 war 包
若是是 web
項目,也能夠打成 war
包,而後使用外部的 Tomcat
容器。
雖然 Spring Boot
提供了一系列自動化配置,來簡化繁重的配置。可是咱們也要了解如何來修改這些默認配置,來適應一些特殊需求的場景。
目前 Spring Boot
支持兩種配置方式,一種是傳統的 properties
文件,以 key=value
形式來表示。例如,要修改默認的端口:
server.port=8081
複製代碼
另外一種是目前比較推薦使用的 YAML
文件。它是以縮進的形式來表示,其結構更加地清晰易讀。例如:
server:
port: 8081
複製代碼
另外,YAML
文件也支持在同一個文件中經過 spring.profiles
屬性來定義多個不一樣的環境的配置。例如,在下面的文件中:
server:
port: 8080
---
server:
port: 8081
spring:
profiles: prod
---
server:
port: 8082
spring:
profiles: test
複製代碼
若是咱們指定爲 test
環境,server.port
就使用 8082
端口;若是指定爲 prod
環境,就使用 8081
端口,不然沒有指定的話,就使用 8080
端口。
可是 YAML
文件有一些不足,它不能經過 @PropertySource
註解來加載指定的 YAML
配置文件。不過能夠經過 @Value
註解。
更多關於 YAML
的詳細語法,能夠參考:阮一峯:YAML 語言教程
對於自定義的配置,要應用到咱們的項目當中,SpringBoot
目前支持兩種讀取方式。它們也都支持和 @PropertySource
配合,來指定使用的配置文件。
1. @Value
一種是剛纔提到的 @Value
,讀取配置到具體的屬性上。
例如,在 application.yml
文件中添加以下配置:
user:
name: TimberLiu
age: 21
address: China
複製代碼
在 User
類就能夠按照以下的方式進行讀取:
@Component
@Setter
@Getter
public class User {
@Value("${user.name}")
public String name;
@Value("${user.age}")
public int age;
@Value("${user.address}")
public String address;
}
複製代碼
2. @ConfigurationProperties
另一種是 @ConfigurationProperties
,讀取配置到類上。
一樣是上面的配置內容,使用 @ConfigurationProperties
就能夠像以下這樣配置:
@Component
@Setter
@Getter
@ConfigurationProperites(prefix="user")
public class User {
public String name;
public Integer age;
public String address;
}
複製代碼
3. 二者的區別
那這兩種方式有什麼區別呢?經過下面這個表格來看一下:
/ | @ConfigurationProperties | @Value |
---|---|---|
功能 | 讀取配置到類上 | 讀取配置到屬性上 |
鬆散綁定 | 支持 | 不支持 |
JSR303 數據校驗 | 支持 | 不支持 |
複雜類型封裝 | 支持 | 不支持 |
下面經過一個例子來講明,例如對於下面的配置內容:
person:
name: timberliu
age: 21
birthday: 2019/4/17
info: {k1: v1,k2: v2}
lists:
- jack
- rose
dog:
last_name: wang # 屬性中的名,last_name 匹配 lastName,鬆散綁定
age: 3
複製代碼
使用 @ConfigurationProperties
能夠以下配置:
@Component
@Getter
@Setter
@ConfigurationProperties("person")
@Validated
public class Person {
// 非空校驗
@NotNull
private String name;
private Integer age;
// 日期類型,數據校驗
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
private Date birthday;
// 複雜類型
private Map<String, String> info;
private List<Object> lists;
private Dog dog;
}
@Component
@Getter
@Setter
@ConfigurationProperties("person.dog")
public class Dog {
private String lastName;
private Integer age;
}
複製代碼
通常來講,項目都會對於不一樣的環境使用不一樣的配置,在 Spring Boot
中,多環境配置的文件名須要知足 application-{profile}.properties
或者 .yml
的格式,其中 profile
對應的環境標識。
至於具體哪一個環境會被加載,須要在 application.properties
文件中經過 spring.profiles.active
屬性進行設置。
例如,若是有三個環境的配置文件:
application-dev.properties
application-test.properties
application-prod.properties
複製代碼
在 application.properties
文件中指定 spring.profiles.active=dev
,就會加載 application-dev.properties
配置文件中的內容。
通常在實際開發中,多環境的配置思路以下:
application.properties
文件中配置一些通用的屬性,並設置 spring.profiles.active=dev
,默認配置爲開發環境。application-{profile}.properties
文件中去配置不一樣環境不一樣的內容。經過前面已經瞭解到,屬性能夠在不少地方進行配置,例如 application.properties
或者 application-{profile}.properties
文件中,命令行中等等。那麼爲了可以更合理地重寫各屬性的值,下面來看一下這些配置的加載順序是怎樣的。因爲這裏加載順序很是多,這裏只列舉一些經常使用的:
java -jar myapplication.jar --server.port=8081
。Java
系統變量。random.*
配置的隨機屬性。Jar
包外部的,針對不一樣 {profile}
環境的配置文件內容,例如 application-{profile}.properties
。Jar
包內部的,針對不一樣 {profile}
環境的配置文件內容,例如 application-{profile}.yml
。Jar
包外部的 application.properties
或 application.yml
。Jar
包內部的 application.properties
或 application.yml
。@Configuration
類中,經過 @PropetySource
註解定義的屬性。SpringApplication.setDefaultProperties
定義的屬性。這些加載順序,越往下優先級越低。
本文介紹了 Spring Boot
的基本概念。其中詳細說了 SpringBoot
的配置文件,例如配置文件的格式、讀取方式,多環境下應該如何配置,及配置文件的加載順序。
下篇文章將詳細說一下 SpringBoot
的啓動方式和自動配置原理。