應(yīng)用場(chǎng)景
在java項(xiàng)目的開(kāi)發(fā)過(guò)程中,配置文件中相關(guān)配置項(xiàng)的值是應(yīng)不同的執(zhí)行環(huán)境所變化的,并且這種變化也可能是事前未知的吮便。
縱向變化-執(zhí)行者
一種是隨著執(zhí)行者的不同而不同愉耙,譬如說(shuō)開(kāi)發(fā)人員開(kāi)發(fā)過(guò)程中debug的環(huán)境(簡(jiǎn)稱dev)、個(gè)人CI與單元測(cè)試環(huán)境(ut)、團(tuán)隊(duì)CI環(huán)境、測(cè)試環(huán)境可能使用不同類型的數(shù)據(jù)庫(kù)和執(zhí)行環(huán)境。
橫向變化-時(shí)間
另外一種是隨著時(shí)間的變化而變化的赃额。例如在筆者所服務(wù)的公司加派,通過(guò)使用模板機(jī)VM的方式提供帶系統(tǒng)、數(shù)據(jù)庫(kù)和基礎(chǔ)數(shù)據(jù)的開(kāi)發(fā)測(cè)試環(huán)境給大家使用跳芳,但是隨著版本不斷上線芍锦,模板機(jī)VM會(huì)不斷被更新。在模板機(jī)被更新后飞盆,需要重新clone環(huán)境并使用娄琉,這時(shí)如IP等信息基本都會(huì)有變化,因此即使是如團(tuán)隊(duì)CI環(huán)境吓歇,可能也會(huì)需要變化孽水。
解決方案1- profile
通過(guò)maven profile來(lái)針對(duì)橫向變化的部分來(lái)形成一個(gè)個(gè)profile,在運(yùn)行時(shí)動(dòng)態(tài)選擇即可。
解決方案2 - filter
在maven profile的基礎(chǔ)上城看,針對(duì)臨時(shí)變化的部分女气,可以通過(guò)filter在runtime動(dòng)態(tài)指定環(huán)境的參數(shù)值。
利用spring框架自身提供的profile機(jī)制
最終的解決方案
針對(duì)公司現(xiàn)有java類產(chǎn)品的開(kāi)發(fā)框架(springMvc)测柠,使用了如下的方式
1炼鞠、將src/main/resouces下的配置文件復(fù)制到src/test/resouces下,對(duì)需要參數(shù)化的配置項(xiàng)的值進(jìn)行參數(shù)化修改轰胁。
key=123 修改為key=${key}
2谒主、在pom.xml中建立dev/ut/ci/qa等profile
<profiles>
<profile>
<id>dev</id>
<!-- 默認(rèn)激活開(kāi)發(fā)配制,使用app_dev.properties來(lái)替換設(shè)置過(guò)慮的資源文件中的${key} -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<filters>
<filter>src/test/resources/app_dev.properties</filter>
</filters>
</build>
</profile>
<profile>
<id>ut</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<filters>
<filter>src/test/resources/app_ut.properties</filter>
</filters>
</build>
</profile>
</profiles>
3赃阀、在pom.xml的<build/>部分加入filter霎肯,指定需要被替換的參數(shù)文件
<build>
<testResources>
<!-- filter global.properties frameworkConfig.properties -->
<testResource>
<directory>src/test/resources</directory>
<includes>
<include>frameworkConfig.properties</include>
<include>cfc_config.properties</include>
</includes>
<filtering>true</filtering>
</testResource>
<!-- inlcude other files like root-context.xml-->
<testResource>
<directory>src/test/resources</directory>
<excludes>
<exclude>frameworkConfig.properties</exclude>
<exclude>cfc_config.properties</exclude>
<exclude>app_*.properties</exclude>
</excludes>
<filtering>true</filtering>
</testResource>
</testResources>
</build>
這里有個(gè)坑要注意,一般在網(wǎng)上搜來(lái)的都是profile/filter介紹都是關(guān)于<resource/>標(biāo)簽的榛斯,其實(shí)對(duì)應(yīng)的是src/main/resouces目錄姿现。如果要操作src/test/resources目錄,則需要使用<testResources/>標(biāo)簽肖抱。
4、在src/test/resouces下建立類似app_dev/app_qa等配置文件异旧,文件中填寫相應(yīng)的配置項(xiàng)的值意述。
如:key=123
5、在pom.xml的<build/> 的filter中增加exclude部分來(lái)剔除4中的配置文件吮蛹,以免污染構(gòu)建后的二進(jìn)制文件夾荤崇。
<exclude>app_*.properties</exclude>
6、如果有臨時(shí)變化潮针,不需要通過(guò)commit到代碼庫(kù)中术荤,則可以在運(yùn)行時(shí),通過(guò)類似
mvn test -Pdev -Dkey=666
的方式來(lái)動(dòng)態(tài)修改key的值每篷。
為什么不用配置中心
筆者所在的公司也建設(shè)了配置中心瓣戚,所有系統(tǒng)在啟動(dòng)時(shí)都需要通過(guò)配置中心來(lái)獲取對(duì)應(yīng)配置項(xiàng)中的值端圈。在其設(shè)計(jì)過(guò)程中,除了prod環(huán)境外子库,也規(guī)劃了dev/qa等環(huán)境舱权。 由于配置中心是一個(gè)web服務(wù),對(duì)于多個(gè)開(kāi)發(fā)/測(cè)試人員仑嗅,如果在同時(shí)針對(duì)某個(gè)系統(tǒng)進(jìn)行開(kāi)發(fā)/測(cè)試宴倍,但使用不同的環(huán)境,其在配置中心的配置項(xiàng)的值也不同仓技,如果使用同一個(gè)配置中心鸵贬,則會(huì)造成配置項(xiàng)的值沖突。
現(xiàn)實(shí)中脖捻,也是通過(guò)模板機(jī)來(lái)部署多套配置中心來(lái)規(guī)避上述問(wèn)題阔逼。但是在開(kāi)發(fā)/單元測(cè)試/集成測(cè)試的過(guò)程中,我們希望配置值能跟隨代碼庫(kù)進(jìn)行配置管理郭变。
With the above configuration, both main/resources and test/resources folders are treated as resources while the second one should be treated as test resources. Because of that, the resources:resources goal handles not only the config.xml but also test-config.xml and both lands in target/classes properly filtered.
Because of default definition, the other goal resources:testResources copies test-config.xml to target/test-classes without applying the filters (as by default filtering is disabled).