一起聊聊 Spring Profiles 的小知識(shí)
?大家好,我是指北君。
最近公司新來(lái)了一個(gè)實(shí)習(xí)生,挺上進(jìn)的,天天追著我問(wèn)問(wèn)題。指北君開(kāi)啟了帶實(shí)習(xí)生打怪升級(jí)之路。吶,今天問(wèn)了一個(gè)關(guān)于 Spring Profiles 的問(wèn)題。
實(shí)習(xí)生:指北君,你知道 Spring Profiles 嗎?
指北君:我知道啊,怎么了?有什么問(wèn)題嗎?
實(shí)習(xí)生:那你可以跟我講講嘛,Spring Profiles到底是什么?有什么用?
指北君:好的,Profiles 是 Spring 框架的核心特性,它允許我們?cè)诓煌?profiles 條件下,對(duì) Spring bean? 有不同的配置實(shí)現(xiàn)。比如說(shuō),我們?cè)谏a(chǎn)環(huán)節(jié)用 prod 標(biāo)記,那我們的 spring bean 構(gòu)造出來(lái)之后就使用了 prod 的配置項(xiàng)。所以我們只要在啟動(dòng)的時(shí)候,設(shè)定好我們想要的 profile ,那我們就能獲得不同的結(jié)果。
實(shí)習(xí)生:那這個(gè) Spring Profile 在項(xiàng)目里怎么使用的呢?
指北君:好,我找個(gè)項(xiàng)目給你看下。
話音剛落,指北君打開(kāi)了 IDEA,一頓操作,找到了一個(gè)配置類。
@Component
@Profile("dev")
public class DevDatasourceConfig
指北君:看到了嗎?我們項(xiàng)目里這個(gè)數(shù)據(jù)源配置類上面有個(gè) @Profile? 注解,里面寫(xiě)了 dev 。就是說(shuō)這個(gè)配置類在 profile=dev 的時(shí)候,才能生效。
實(shí)習(xí)生:那這個(gè)挺簡(jiǎn)單的呀。
指北君:是的呀,使用起來(lái)很簡(jiǎn)單的,哦對(duì)了,這里有個(gè)小技巧。如果我們只是不想在特定環(huán)境下配置某個(gè)配置類的話,也有很簡(jiǎn)單的操作方式。
@Component
@Profile("!dev")
public class DevDatasourceConfig
你看出區(qū)別了嗎?
實(shí)習(xí)生:就是 dev 之前加了一個(gè) !(嘆號(hào))。其他沒(méi)有變化。
指北君:是的,就是這樣,這也是一個(gè)常用的技巧。
實(shí)習(xí)生:代碼里雖然這樣配置好了,那項(xiàng)目啟動(dòng)怎么知道啟用了哪一個(gè)配置項(xiàng)呢?
指北君:?jiǎn)⒂媚囊粋€(gè)配置,這邊有很多種方式可以實(shí)現(xiàn)。
1.我們?cè)陧?xiàng)目中的 application.properties 文件里直接進(jìn)行配置即可
spring.profiles.active=dev
2.通過(guò)硬編碼實(shí)現(xiàn) WebApplicationInitializer 接口,配置 ServletContext 來(lái)激活配置
@Configuration
public class MyWebApplicationInitializer
implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
servletContext.setInitParameter(
"spring.profiles.active", "dev");
}
}
3.直接在 ConfigurableEnvironment 中實(shí)現(xiàn)設(shè)置,使用 spring boot 的朋友應(yīng)該都知道,系統(tǒng)所有的配置項(xiàng)都是來(lái)自于 ConfigurableEnvironment 。
@Autowired
private ConfigurableEnvironment env;
...
env.setActiveProfiles("dev");
4.命令行JVM啟動(dòng)參數(shù)
-Dspring.profiles.active=dev
5.通過(guò) export 環(huán)境變量來(lái)實(shí)現(xiàn)
export spring_profiles_active=dev
嗯, 學(xué)會(huì)了這幾種方法,你已經(jīng)可以在絕大部分場(chǎng)景下,游刃有余地使用 profile 了。
實(shí)習(xí)生:那我還有個(gè)問(wèn)題,既然這樣配置的話,那我項(xiàng)目里有多個(gè)profile, 萬(wàn)一我手抖,沒(méi)有用你說(shuō)的這幾種配置好呢?那會(huì)怎么樣?
指北君:這個(gè)你放心,spring boot 有兜底方法,你想啊,你在一些項(xiàng)目沒(méi)有用到 profile 的時(shí)候,spring boot 是怎么啟動(dòng)的呢?spring boot 項(xiàng)目會(huì)自動(dòng)使用默認(rèn)配置
spring.profiles.default=none
也就是說(shuō),spring boot 啟動(dòng)了,但是沒(méi)有加載任何被@Profile 等標(biāo)記的配置類。只會(huì)加載沒(méi)有被標(biāo)記的配置類。
實(shí)習(xí)生:懂了,我看我們項(xiàng)目里,有很多類似 @Profile("db") @Profile("mysql") 之類的,那像這種多個(gè)的怎么使用的?
指北君:是的,我們項(xiàng)目中,不同的模塊都分開(kāi)配置了, 我給你舉個(gè)例子怎么使用的。
-Dspring.profiles.active=dev,db,mysql
就像這樣,直接逗號(hào)分割,拼接上去就行了。
實(shí)習(xí)生:那這樣好像比較麻煩啊,萬(wàn)一搞漏掉了就給自己挖坑了。
指北君:對(duì)的,這就是要仔細(xì)了,以前一直要靠自己的。現(xiàn)在就不會(huì)有這個(gè)問(wèn)題了,spring boot 團(tuán)隊(duì)也意識(shí)到這個(gè)問(wèn)題了,在 Spring boot 2.4 開(kāi)始已經(jīng)支持分組了。
spring.profiles.group.production[0]=proddb
spring.profiles.group.production[1]=prodmq
我們平時(shí)啟動(dòng)的時(shí)候只要指定 spring.profiles.active=production? 就行了, prodb 和 prodmq 同樣就能成功配置進(jìn)來(lái)。Spring Profiles 的相關(guān)內(nèi)容差不多都講完了,你還有什么疑問(wèn)嗎?
實(shí)習(xí)生:現(xiàn)在基本沒(méi)有了,等我遇到再來(lái)找你這大佬。
指北君:隨時(shí)歡迎,現(xiàn)在是我在帶你,不要給我丟臉就行。哈哈哈。
總結(jié)
本文講述了 Spring Profiles 的配置使用,和如果在啟動(dòng)的時(shí)候,選擇特定的 profile 。也講述了一些使用過(guò)程中的一些小技巧,希望對(duì)你有幫助。