文章目录
  1. 1. Spring启用一个profile
  2. 2. Maven profile配置
  3. 3. web.xml内容替换
  4. 4. 优化:打包时不修改src目录下的web.xml
  5. 5. 为什么不使用多个web.xml文件

在Maven的pom.xml和Spring框架中,都有profile这个概念。profile是用于区分各种环境的,例如开发环境、测试环境、正式环境等。Maven的profile经常用于在打包时根据指定环境打入不同的配置文件配置,如数据库配置。Spring的Profile可以用于在不同的环境下加载不同的bean,例如@Profile注解。本文介绍如何将二者整合。

Spring启用一个profile

Spring启用某个profile有多种方式,为了便于整合Maven,这里通过web.xml方式启用:

1
2
3
4
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>dev</param-value>
</context-param>

在默认情况下,会启用Spring的dev profile,即开发环境。

Maven profile配置

在pom.xml中,可以配置test和product两个profile,分别对应测试环境和正式环境。这里也可以根据具体情况自定义。

1
2
3
4
5
6
7
8
9
10
<profiles>
<profile>
<id>test</id>
...
</profile>
<profile>
<id>product</id>
...
</profile>
</profiles>

此时,运行mvn clean package -Ptest就会使用id为test的profile内的配置打包,mvn clean package -Pproduct就是用来打正式环境包的命令。

web.xml内容替换

在web.xml中<param-value>dev</param-value>是指定Spring的profile,接下里要实现这个内容的替换,让mvn clean package -Ptest打包出来的web.xml变成<param-value>test</param-value>。这里可以使用maven-antrun-plugin来实现字符串替换:

1
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<profiles>
<profile>
<id>test</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>compile</phase>
<configuration>
<target>
<!-- web.xml中的<param-value>dev</param-value>替换为<param-value>test</param-value> -->
<replace file="${basedir}/src/main/webapp/WEB-INF/web.xml"
token="&lt;param-value&gt;dev&lt;/param-value&gt;"
value="&lt;param-value&gt;test&lt;/param-value&gt;" />

</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>product</id>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>compile</phase>
<configuration>
<target>
<!-- web.xml中的<param-value>dev</param-value>替换为<param-value>product</param-value> -->
<replace file="${basedir}/src/main/webapp/WEB-INF/web.xml"
token="&lt;param-value&gt;dev&lt;/param-value&gt;"
value="&lt;param-value&gt;product&lt;/param-value&gt;" />

</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>

以上的<replace file="" token="" value="" />中分别用于指定文件、待替换字符串、替换后的字符串。这里为什么不写成token="dev"?考虑到”dev”这个字符串太短,可能会在web.xml中别的地方出现,防止误伤,所以这里会用token="&lt;param-value&gt;dev&lt;/param-value&gt;"

以上配置加入到pom.xml中后,再通过mvn clean package -Ptestmvn clean package -Pproduct命令打包,打包好的war包解压出来,可以发现<param-value>dev</param-value>被替换成了<param-value>test</param-value><param-value>product</param-value>。此时便完成了Maven和Spring的profile的整合。

优化:打包时不修改src目录下的web.xml

如果使用mvn clean package -Ptestmvn clean package -Pproduct打包,会造成项目中的web.xml修改替换,此时如果忘了改回来,会造成一些问题,如再次打不同环境的包就找不到<param-value>dev</param-value>来replace了,还有如果此时在开发中调试会误启用其他的Spring profile。

为了解决这个问题,我们可以通过maven-antrun-plugin插件在replace前将web.xml拷贝一份出来,在拷贝出的web.xml文件上执行replace操作,打包时将拷贝出的web.xml打入war包,从而不影响原有的web.xml文件内容。

1
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<profiles>
<profile>
<id>test</id>
<properties>
<!-- 使用target/web-xml中的web.xml文件打入war包 -->
<maven.war.webxml>${basedir}/target/web-xml/web.xml</maven.war.webxml>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>compile</phase>
<configuration>
<target>
<!-- 将web.xml拷贝一份到target/web-xml目录下 -->
<copy file="${basedir}/src/main/webapp/WEB-INF/web.xml"
todir="${basedir}/target/web-xml" />

<!-- 拷贝后的web.xml中的<param-value>dev</param-value>替换为<param-value>test</param-value> -->
<replace file="${basedir}/target/web-xml/web.xml"
token="&lt;param-value&gt;dev&lt;/param-value&gt;"
value="&lt;param-value&gt;test&lt;/param-value&gt;" />

</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>product</id>
<properties>
<!-- 使用target/web-xml中的web.xml文件打入war包 -->
<maven.war.webxml>${basedir}/target/web-xml/web.xml</maven.war.webxml>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>compile</phase>
<configuration>
<target>
<!-- 将web.xml拷贝一份到target/web-xml目录下 -->
<copy file="${basedir}/src/main/webapp/WEB-INF/web.xml"
todir="${basedir}/target/web-xml" />

<!-- 拷贝后的web.xml中的<param-value>dev</param-value>替换为<param-value>product</param-value> -->
<replace file="${basedir}/target/web-xml/web.xml"
token="&lt;param-value&gt;dev&lt;/param-value&gt;"
value="&lt;param-value&gt;product&lt;/param-value&gt;" />

</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>

为什么不使用多个web.xml文件

以上是使用了一种web.xml文件字符串替换的方式来实现Maven和Spring的profile整合。另外还有一种配置多个web.xml文件的方式,即为每个profile拷贝一份web.xml,修改相应spring.profiles.active的值,pom.xml中每个profile指定对应的maven.war.webxml将相应的web.xml打入war包。如果项目需要经常修改web.xml文件内容,每次都要修改好几份web.xml文件会非常麻烦,所以不推荐使用。

文章目录
  1. 1. Spring启用一个profile
  2. 2. Maven profile配置
  3. 3. web.xml内容替换
  4. 4. 优化:打包时不修改src目录下的web.xml
  5. 5. 为什么不使用多个web.xml文件