有非常多的資訊都會寫在設定檔,主要就是那些可能會頻繁變更的資訊,例如資料庫連接的帳號密碼等
Spring Boot 的設定檔有兩種,分別是 application.properties 和 application.yml
這兩種的差別就差在撰寫方式的不同,直接來看看這兩個檔案:
application.yml:
spring:
datasource:
url : jdbc:oracle:thin:@localhost:1521:XE
driverClassName : oracle.jdbc.driver.OracleDriver
username : RUYUT
password : abcd1234
application.properties:
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:XE
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.username=RUYUT
spring.datasource.password=abcd1234
該檔案存放的路徑如下:
註:雖然這兩個檔案可以同時存在,但非常不建議。預設會先讀取 yml,再讀取 properties,所以很可能發生找半天才發現原來問題出在設定檔被蓋掉的情況
RuyutExample/
`-- src/
`-- main
`-- resources/
|-- application.yml
`-- application.properties
讀取設定值
我們直接建立一個 ConfigurationController ,本次就直接在這個控制器中做示範範例設定檔內容如下:
ruyut.blog.url=https://www.ruyut.com/
讀取設定檔中的 "ruyut.blog.url" 設定值至 applicationName 變數:
@Value("${ruyut.blog.url}")
private String ruyutBlogUrl;
完整呼叫範例:
執行程式後使用瀏覽器開啟 http://localhost:8080/configuration 即可看到設定值有成功被讀取
package app.ruyut.ruyutexample.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class ConfigurationController {
@Value("${ruyut.blog.url}")
private String ruyutBlogUrl;
@GetMapping("configuration")
public ResponseEntity<String> configuration() {
return ResponseEntity.ok(ruyutBlogUrl);
}
}
設定檔預設值
如果這時候把剛剛的設定值刪掉,執行程式時會拋出下列錯誤:
Error creating bean with name 'configurationController': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'ruyut.blog.url' in value "${ruyut.blog.url}"
原因是因為設定值不存在,所以在自動注入的時候發生錯誤,要避免這個問題的方式就是加上預設值
只要在後面加上冒號(:),冒號後面的就是預設值
@Value("${ruyut.blog.url:https://ruyut.app}")
private String ruyutBlogUrl;
此時再執行程式已經不會出現錯誤了
設定檔類別
假設我們有很多設定值,我們應該要新增一個組態設定的類別來存放特定類別的所有設定值設定檔類別範例:
package app.ruyut.ruyutexample.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Value("${ruyut.blog.url:https://ruyut.app}")
public String ruyutBlogUrl;
}
讀取範例:
package app.ruyut.ruyutexample.controller;
import app.ruyut.ruyutexample.config.AppConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class ConfigurationController {
@Autowired
private AppConfig appConfig;
@GetMapping("configuration")
public ResponseEntity<String> configuration() {
return ResponseEntity.ok(appConfig.ruyutBlogUrl);
}
}
解決自動注入到靜態成員 NULL
不知道你有沒有發現,如果在 @Value 下面的那個變數是靜態成員(static),則那個變數,無法被正常賦值(注入),該變數都會是 null
@Value("${ruyut.blog.url:https://ruyut.app}")
public static String ruyutBlogUrl;
嗯,這就是 Spring Boot 法律規範,無法處理...
不過,可以用個小方法繞過
@Value("${ruyut.blog.url:https://ruyut.app}")
private void setRuyutBlogUrl(String ruyutBlogUrl) {
this.ruyutBlogUrl = ruyutBlogUrl;
}
public static String ruyutBlogUrl;
完美,這就是程式的魅力所在!
留言
張貼留言
如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com