一起來學SpringBoot | 第二篇:SpringBoot配置詳解
文章目錄
- 自定義屬性配置
- 自定義檔案配置
- 多環境化配置
- 外部命令引導
- 總結
- 說點什麼
SpringBoot 是為了簡化 Spring 應用的建立、執行、除錯、部署等一系列問題而誕生的產物,自動裝配的特性讓我們可以更好的關注業務本身而不是外部的XML配置,我們只需遵循規範,引入相關的依賴就可以輕易的搭建出一個 WEB 工程
上一篇介紹了 SpringBoot 由來及構建方式,通過第一章的教程我們對 SpringBoot 不在感到陌生,可以發現 SpringBoot 雖然幹掉了 XML 但未做到 零配置,它體現出了一種 約定優於配置,也稱作按約定程式設計,是一種軟體設計正規化,旨在減少軟體開發人員需做決定的數量,獲得簡單的好處,而又不失靈活性。 一般情況下預設的配置足夠滿足日常開發所需,但在特殊的情況下,我們往往需要用到自定義屬性配置、自定義檔案配置、多環境配置、外部命令引導等一系列功能。不用擔心,這些 SpringBoot 都替我們考慮好了,我們只需要遵循它的規則配置即可
準備前提
為了讓 Spring Boot 更好的生成配置元資料檔案,我們需要新增如下依賴(該依賴可以不新增,但是在 IDEA 和 STS 中不會有屬性提示,沒有提示的配置就跟你用記事本寫程式碼一樣苦逼,出個問題弄哭你去),該依賴只會在編譯時呼叫,所以不用擔心會對生產造成影響…
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
自定義屬性配置
在 application.properties 寫入如下配置內容
my1.age=22
my1.name=battcn
其次定義 MyProperties1.java 檔案,用來對映我們在 application.properties 中的內容,這樣一來我們就可以通過操作物件的方式來獲得配置檔案的內容了
package com.battcn.properties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * @author Levin * @since 2018/4/23 0023 */ @Component @ConfigurationProperties(prefix = "my1") public class MyProperties1 { private int age; private String name; // 省略 get set @Override public String toString() { return "MyProperties1{" + "age=" + age + ", name='" + name + '\'' + '}'; } }
接下來就是定義我們的 PropertiesController 用來注入 MyProperties1 測試我們編寫的程式碼,值得注意的是 Spring4.x 以後,推薦使用建構函式的形式注入屬性…
import com.battcn.properties.MyProperties1;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author Levin
* @since 2018/4/23 0023
*/
@RequestMapping("/properties")
@RestController
public class PropertiesController {
private static final Logger log = LoggerFactory.getLogger(PropertiesController.class);
private final MyProperties1 myProperties1;
@Autowired
public PropertiesController(MyProperties1 myProperties1) {
this.myProperties1 = myProperties1;
}
@GetMapping("/1")
public MyProperties1 myProperties1() {
log.info("=================================================================================================");
log.info(myProperties1.toString());
log.info("=================================================================================================");
return myProperties1;
}
}
2018-04-23 15:51:43.145 INFO 15352 --- [nio-8080-exec-2] c.b.controller.PropertiesController : =================================================================================================
2018-04-23 15:51:43.145 INFO 15352 --- [nio-8080-exec-2] c.b.controller.PropertiesController : MyProperties1{age=22, name='battcn'}
2018-04-23 15:51:43.145 INFO 15352 --- [nio-8080-exec-2] c.b.controller.PropertiesController : =================================================================================================
自定義檔案配置
定義一個名為 my2.properties 的資原始檔,自定義配置檔案的命名不強制 application 開頭
my2.age=22
my2.name=Levin
[email protected]
其次定義 MyProperties2.java 檔案,用來對映我們在 my2.properties 中的內容。
package com.battcn.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
* @author Levin
* @since 2018/4/23 0023
*/
@Component
@PropertySource("classpath:my2.properties")
@ConfigurationProperties(prefix = "my2")
public class MyProperties2 {
private int age;
private String name;
private String email;
// 省略 get set
@Override
public String toString() {
return "MyProperties2{" +
"age=" + age +
", name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}
}
接下來在 PropertiesController 用來注入 MyProperties2 測試我們編寫的程式碼
@GetMapping("/2")
public MyProperties2 myProperties2() {
log.info("=================================================================================================");
log.info(myProperties2.toString());
log.info("=================================================================================================");
return myProperties2;
}
2018-04-23 15:59:45.395 INFO 6232 --- [nio-8080-exec-4] c.b.controller.PropertiesController : =================================================================================================
2018-04-23 15:59:45.395 INFO 6232 --- [nio-8080-exec-4] c.b.controller.PropertiesController : MyProperties2{age=22, name='Levin', email='[email protected]'}
2018-04-23 15:59:45.395 INFO 6232 --- [nio-8080-exec-4] c.b.controller.PropertiesController : =================================================================================================
多環境化配置
在真實的應用中,常常會有多個環境(如:開發,測試,生產等),不同的環境資料庫連線都不一樣,這個時候就需要用到spring.profile.active 的強大功能了,它的格式為 application-{profile}.properties,這裡的 application 為字首不能改,{profile} 是我們自己定義的。
建立 application-dev.properties、application-test.properties、application-prod.properties,內容分別如下
application-dev.properties
server.servlet.context-path=/dev
application-test.properties
server.servlet.context-path=/test
application-prod.properties
server.servlet.context-path=/prod
在 application.properties 配置檔案中寫入 spring.profiles.active=dev,這個時候我們在次訪問 http://localhost:8080/properties/1 就沒用處了,因為我們設定了它的context-path=/dev,所以新的路徑就是 http://localhost:8080/dev/properties/1 ,由此可以看出來我們啟用不同的配置讀取的屬性值是不一樣的
外部命令引導
前面三種方式都是基於配置檔案層面的,那麼有沒有辦法外部引導呢,假設這樣的場景,我們對已經開發完成的程式碼打包釋出,期間在測試環境測試通過了,那麼即可釋出上生產,這個時候是修改application.properties的配置方便還是直接在命令引數配置方便呢,毫無疑問是後者更有說服力。預設情況下,SpringApplication 會將命令列選項引數(即:–property,如–server.port=9000)新增到Environment,命令列屬性始終優先於其他屬性源。
如何測試?
1. 進入到專案目錄,此處以我本地目錄為主:F:/battcn-workspace/spring-boot2-learning/chapter2 2. 然後開啟 cmd 程式,不會在當前目錄開啟 cmd 的請自行百度,輸入:mvn package 3. 打包完畢後進入到:F:/battcn-workspace/spring-boot2-learning/chapter2/target 目錄中去,我們可以發現一個名為chapter2-0.0.1-SNAPSHOT.jar 的包 4. 接著在開啟 cmd 程式,輸入:java -jar chapter2-0.0.1-SNAPSHOT.jar --spring.profiles.active=test --my1.age=32。仔細觀察spring.profiles.active=test、my1.age=32 這倆配置的鍵值是不是似曾相識(不認識的請從開頭認真閱讀) 5. 最後輸入測試地址:http://localhost:8080/test/properties/1 我們可以發現返回的JSON變成了 {“age”:32,“name”:“battcn”} 表示正確
總結
掌握@ConfigurationProperties、@PropertySource 等註解的用法及作用 掌握編寫自定義配置 掌握外部命令引導配置的方式 目前很多大佬都寫過關於 SpringBoot 的教程了,如有雷同,請多多包涵,本教程基於最新的 spring-boot-starter-parent:2.0.1.RELEASE編寫,包括新版本的特性都會一起介紹…