通常開發、測試及發布環境使用的各種properties參數不同,因此application.properties需依環境設定不同參數,而Spring Profile能依不同環境切換讀取的application.properties。
典型的應用場景是資料庫源設定。開發、測試、發布使用的資料庫不同,因此在application.properties必須有不同的資料庫源(datasource)設定。
Spring Profile讓我們可以設定多個不同環境的properties檔,並設定spring.profiles.active參數值來切換要讀取的properties檔。
在預設的application.properties中設定spring.profiles.active參數後,Spring啟動時會改去讀取application-{profile}.properties的properties檔。{profile}為spring.profiles.active的設定值。
例如下面設定兩個properties檔,分別為預設的application.properties及開發時用的application-dev.properties。
在application.properties中設定了spring.profiles.active=dev,因此啟動時會改去讀取application-dev.properties的設定
application.properties
spring.profiles.active=dev
server.servlet.context-path=/demo
server.port=8080
demo.name=demo-default
application-dev.properties
server.servlet.context-path=/demo
server.port=8081
demo.name=demo-dev
建立一個Controller來測試(注意預設及dev使用的port不同),則印出application-dev.properties中設定的內容。
DemoController
@RestController
public class DemoController {
@Value("${demo.name}")
private String name;
@GetMapping(value = "/print")
public String print() {
System.out.println(name); // demo-dev
return name;
}
}
spring.profiles.active可以設定多個值,例如spring.profiles.active=dev,test,prod。若設定多個profile,則最後面的設定會覆蓋前面的設定。
Spring透過ConfigFileApplicationListener去讀取application.properties的spring.profiles.active參數值並生成Profile物件,最終放入Deque<Profile>集合中。當Spring啟動時若此集合中有值,則Spring會從Deque<Profile>集合中順序取出載入對應的properties檔。
下面是本篇文章來源的小故事。
昨天去某公司面試資深工程師被問到「在Spring Boot是怎麼依不同環境設定不同的properties」。之前我從未設定過(因為通常有人設定好了),所以我回答「Spring內部大概有個mapping表之類的東西吧,會依在某個地方設定的名稱去讀取對應的properties」。結果被洗臉,面試官回答「用Spring Profile就好了,這是基本你應該要知道的東西」,「這是基本你應該知道」,對方強調了兩次。
每次碰到這種面試都很無言,這Google就可查到怎麼設定5分鐘搞定的事,我為什麼要去背誦呢?這跟問Base64 Encode的64代表什麼意思差不多。現在是21世紀了我的老天。
離開前的當下我很不高興就停下腳步反問面試官「Base64 Encode的64代表什麼意思」這"基本"的問題(這經典的問題出自於雷技科技面試﹚,對方也不知道。那意思是對方不夠資深嗎?
我現在能開始理解為什麼FANNG要考LeetCode的原因了。
沒有留言:
張貼留言