maven 多环境打包
Maven 多环境配置打包方式
使用 profiles
<profiles>
<profile>
<id>local</id>
<properties>
<environment>local</environment>
<env>LOCAL</env>
</properties>
</profile>
<profile>
<id>dev</id>
<properties>
<environment>dev</environment>
<env>DEV</env>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<environment>test</environment>
<env>TEST</env>
</properties>
</profile>
<profile>
<id>production</id>
<properties>
<environment>production</environment>
<!-- 为什么要用大写? -->
<env>PRODUCTION</env>
</properties>
</profile>
</profiles>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
修改 build 添加 filter
<build>
<filters>
<!-- src/main/filters 为 maven 默认位置 -->
<filter>src/main/filters/${environment}.fkhwl.properties</filter>
</filters>
<!-- 过滤 resources 下的所有配置文件 -->
<resources>
<resource>
<!-- 配置需要被替换的资源文件路径 -->
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<!-- 加入 banner 打印输出文件 -->
<include>**/*.banner</include>
<!-- 加入 dubbo 配置文件 -->
<include>**/dubbo/*</include>
</includes>
<excludes>
<!--排除 jrebel 配置文件-->
<exclude>rebel.xml</exclude>
</excludes>
</resource>
</resources>
<!-- junit 测试用, 不将 junit 使用的配置打包 -->
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.banner</include>
</includes>
</testResource>
</testResources>
</build>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
使用命令打包
mvn clean install -Dmaven.test.skip=true -Pdev
使用 @ 代替 $
如果 resource 中存在 js, 且与 maven 内置变量相同, 会将 $ 全部替换为 maven 的参数 所有这里使用 @ 替换掉 $.
原理
maven 会使用 filter 中的文件属性替换所有 resource include 的文件中的占位符
使用 context:property-placeholder
有些参数在某些阶段中是常量。
- 在开发阶段我们连接数据库时的url,username,password等信息
- 分布式应用中client端的server地址,端口等
这些参数在不同阶段之间又往往需要改变
期望:有一种方案可以方便我们在一个阶段内不需要频繁写一个参数的值,而在不同阶段间又可以方便的切换参数的配置信息
解决:spring3中提供了一种简便的方式就是 <content:property-placeholder>
元素
只需要在spring配置文件中添加一句:
<context:property-placeholder location="classpath:jdbc.properties"/>
或者
<bean id="propertyPlaceholderConfigurer" class="org.springframework,beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>jdbc.properties<value/>
</list>
</property>
</bean>
2
3
4
5
6
7
即可,这里的location值为参数配置文件的位置,配置文件通常放到src目录下,参数配置文件的格式即键值对的形式,
#jdbc配置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=root
password=root
2
3
4
5
行内#号后面部分为注释
这样一来就可以为spring配置的bean的属性设置值了,比如spring有一个数据源的类
<bean id="dataSource" class="org.springframework,jdbc,datasource.DriverManagerDataSource">
<property name="driverClassName" value="${driverClassName}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</bean>
2
3
4
5
6
甚至可以将 ${} 这种形式的变量用在spring提供的注解当中,为注解的属性提供值(下面会讲到)
Spring容器采用反射扫描的发现机制,在探测到Spring容器中有一个 org.springframework.beans.config.PropertyPlaceholderConfigurer的Bean就会停止对剩余PropertyPlaceholderConfigurer的扫描,
换句话说,即Spring容器仅允许最多定义一个PropertyPlaceholderConfigurer 或 <content:property-placeholder>
其余的会被Spring忽略
由于Spring容器只能有一个PropertyPlaceholderConfigurer,如果有多个属性文件,这时就看谁先谁后了,先的保留 ,后的忽略。
还有一种情况,是Spring 自动注入 properties文件中的配置:要自动注入properties文件中的配置,需要在Spring配置文件中添加 org.springframework.beans.factory.config.PropertiesFactoryBean
和org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer
的实例配置
<bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value> classpath*:application.properties</value>
</list>
</property>
</bean>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
<property name="properties" ref="configProperties" />
</bean>
2
3
4
5
6
7
8
9
10
在这个配置文件中我们配置了注解扫描,和configProperties实例和propertyConfigurer实例,这样我们就可以在java类中自动注入配置了
@Component
public class Test{
@Value("#{configProperties['userName']}")
private String userName;
public String getUserName(){
return userName;
}
}
2
3
4
5
6
7
8
9
10
自动注入需要使用 @Value 这个注解,这个注解的格式 #{configProperties['userName']}
其中configProperties是我们在配置文件中配置的bean的 id, userName 是在配置文件中配置的项
在Spring中的xml中使用>标签导入配置文件时,想要导入多个properties配置文件,如下:
<context:property-placeholderlocation="classpath:db.properties " />
<context:property-placeholderlocation="classpath:zxg.properties " />
2
结果发现不行,第二个配置文件始终读取不到,后来发现 <context:property-placeholder>
标签在Spring配置文件中只能存在一份!!!Spring容器是采用反射扫描的发现机制,通过标签的命名空间实例化实例,当Spring探测到容器中有一个org.springframework.beans.factory.config.PropertyPlaceholderCVonfigurer
的Bean就会停止对剩余PropertyPlaceholderConfigurer的扫描,即只能存在一个实例。
<context:property-placeholder
location=""
file-encoding=""
ignore-resource-not-found=""
ignore-unresolvable=""
properties-ref=""
local-override=""
system-properties-mode=""
order=""
/>
2
3
4
5
6
7
8
9
10
那如果有多个配置文件怎么办呢?那就多个文件之间以“,”分隔,如下:
<context:property-placeholderlocation="classpath:db.properties,classpath:monitor.properties" />
值得注意的是:多个配置文件将依次加载,如果后一个文件中有和前面某一个文件中属性名是相同的,最终取的值是后加载的值。