运行环境包括:数据库切换,各种配置文件变动,变量的变化
2、实现方式,配置maven的profile和properties,配置spring beans的profile实现层次加载
3、多种实现方式对比
一、糟糕的实现方式
每一种环境建立一个文件夹,文件夹中存放环境所需的全量数据,配置的重复度高。如果需要更新配置,必须把所有的环境都修改。如果有10个或以上的环境,那搞起来就让人骂娘了,改动的越多出错的概率越大。这些都是冗余的东西,相同的配置都是可以提取"公因式"的,没必要每一个环境都配一遍。
二、好的实现
原则:
1、不出现重复
2、能够覆盖到所有环境
方式:
1、一个公共配置,把所有的配置都覆盖到,作为默认的环境,比如是开发环境(dev)
2、不同环境会发生的变化的key,只需要配置变化的即可,使用spring <beans profile> 选择不同的环境
3、如果某些key每个环境都有变化,可以考虑放在maven的<properties>中,每个环境都作配置,构建的时候会替换
实现:
1、配置多个环境和<properties>,要在maven中作如下配置:
<profiles>
<profile>
<id>local</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<profile.id>local</profile.id>
<profile.activation>local</profile.activation>
<profiles.default>local</profiles.default>
<profiles.active>local</profiles.active>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<profile.id>test</profile.id>
<profile.activation>test</profile.activation>
<profiles.default>test</profiles.default>
<profiles.active>test</profiles.active>
</properties>
</profile>
<profile>
<id>production</id>
<properties>
<profile.id>test</profile.id>
<profile.activation>production</profile.activation>
<profiles.default>production</profiles.default>
<profiles.active>production</profiles.active>
</properties>
</profile>
</profiles>
注:
1、<id>表示环境的名称
2、<properties>中的元素可以随意命名,就是自定义的变量,每个环境中所有key要对应
3、activeByDefault 如果为true,则该profile是默认的
2、要实现properties中的变量在构建时替换文件中key,则要做如下配置:
<build>
<finalName>test-web</finalName>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<filtering>true</filtering>
<directory>src/main/webapp</directory>
<includes>
<include>**/web.xml</include>
</includes>
</resource>
</resources>
</build>
注:1、resource表示构建时要被扫描到的资源文件
2、includes 表示包含的文件,excludes表示排除的文件
3、filtering为true时这个resource才会生效,默认false
可能被覆盖的文件和key如下图:
注:1、图中base 表示公共配置所在,配置全量的key
2、local、test、production表示具体的某个环境特有的数据,是变量和增量数据
3、采用先加载base的内容,后加载具体环境中的内容,后面的会覆盖前面的,实现方式如下:
<!-- 开发环境配置文件 -->
<beans profile="local">
<context:property-placeholder
location="classpath*:base/*.properties,classpath*:local/*.properties"/>
<bean id="myList" class="java.util.ArrayList">
<constructor-arg>
<list>
<value>1</value>
<value>2</value>
<value>${jdbc.url}</value>
</list>
</constructor-arg>
</bean>
</beans>
<!-- 测试环境配置文件 -->
<beans profile="test">
<context:property-placeholder
location="classpath*:base/*.properties,classpath*:test/*.properties" ignore-resource-not-found="true"/>
<bean id="myList" class="java.util.ArrayList">
<constructor-arg>
<list>
<value>4</value>
<value>5</value>
<value>${jdbc.url}</value>
</list>
</constructor-arg>
</bean>
</beans>
<!-- 生产环境配置文件 -->
<beans profile="production">
<context:property-placeholder
location="classpath*:base/*.properties,classpath*:production/*.properties"/>
<bean id="myList" class="java.util.ArrayList">
<constructor-arg>
<list>
<value>7</value>
<value>8</value>
<value>${jdbc.url}</value>
</list>
</constructor-arg>
</bean>
</beans>
注:1、profile=local/test/production,这就是具体的环境
2、context:property-placeholder location= 这里是加载配置文件路径,要注意顺序,后面的会覆盖前面的,不是文件级别的覆盖,是key级别
3、profile的选择可以使用spring.profiles.default和spring.profiles.active来配置,这两个变量可以配置在web.xml中,也可以配置在jvm options(-Dspring.profiles.active)
注:1、如果配置在web.xml中,可以继续提取到maven 的properties中,构建时替换即可