Maven 整合 spring profile实现多环境自动切换

转载自:https://zilongsky-gmail-com.iteye.com/blog/2032001

 

profile主要用在项目多环境运行的情况下,比如开发环境、测试环境、线上生产环境。 
我负责的项目某个数据管理后台涉及到包含测试环境在内的12个不同的运行环境,所以每次发布都很蛋疼很纠结,配置改过来改过去,到最后有些环境都忘了怎么配的。 
下面以这个项目为例介绍。 
准备条件:spring3.x、Maven 2 

这里是整合spring的profile和Maven的profile功能 

spring的profile配置 

首先是spring的配置数据源和属性文件 
 

Xml代码 

 Maven 整合 spring profile实现多环境自动切换

  1. <beans profile="xmj_old">  
  2.         <bean id="dataSource"   
  3.             class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
  4.             <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
  5.             <property name="url"   
  6.                 value="jdbc:mysql://127.0.0.1:3306/db1?characterEncoding=utf8" />  
  7.             <property name="password" value="123456" />  
  8.             <property name="username" value="abc" />  
  9.         </bean>  
  10.         <bean id="messageSource"   
  11.             class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  
  12.             <property name="basenames">  
  13.                 <list>  
  14.                     <value>classpath:messages_zh_CN</value>  
  15.                     <value>classpath:messages/messages_en_US-xmj_old</value>  
  16.                 </list>  
  17.             </property>  
  18.         </bean>  
  19.     </beans>  
  20.     <beans profile="xmj_new">  
  21.         <bean id="dataSource"   
  22.             class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
  23.             <property name="driverClassName" value="com.mysql.jdbc.Driver" />  
  24.             <property name="url"   
  25.                 value="jdbc:mysql://127.0.0.1:3306/db1?characterEncoding=utf8" />  
  26.             <property name="password" value="123456" />  
  27.             <property name="username" value="abc" />  
  28.         </bean>  
  29.         <bean id="messageSource"   
  30.             class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  
  31.             <property name="basenames">  
  32.                 <list>  
  33.                     <value>classpath:messages_zh_CN</value>  
  34.                     <value>classpath:messages/messages_en_US-xmj_new</value>  
  35.                 </list>  
  36.             </property>  
  37.         </bean>  
  38.     </beans>  
  39. ...  
  40. ...  
  41. ...  



这里的message_en_US-*系列属性文件是配置站点的名称和黑名单的位置: 
 

Java代码 

 Maven 整合 spring profile实现多环境自动切换

  1. resource.blacklist.dir=/var/resource/blacklist.txt  
  2. system.title.id=system.xmj_old.title  



**spring的profile 

profile是配置完了,但还要**spring的profile特性。 
在web.xml做如下配置: 
 

Xml代码 

 Maven 整合 spring profile实现多环境自动切换

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



这样就**spring配置文件中的profile为xmj_old的配置,但这样手动配置依然要改web.xml配置。 
Maven也带了profile的功能,而且我们的项目一般都是由Maven管理的,下面介绍Maven配置profile。 

Maven 配置profile 
Maven配置profile也很简单,举例如下: 

Xml代码 

 Maven 整合 spring profile实现多环境自动切换

  1. <profiles>  
  2.         <profile>  
  3.             <id>xmj_old</id>  
  4.             <activation>  
  5.                 <activeByDefault>true</activeByDefault>  
  6.             </activation>  
  7.             <properties>  
  8.                 <profiles.activation>xmj_old</profiles.activation>  
  9.             </properties>  
  10.             <build>  
  11.                 <plugins>  
  12.                     <plugin>  
  13.                         <groupId>org.codehaus.mojo</groupId>  
  14.                         <artifactId>tomcat-maven-plugin</artifactId>  
  15.                         <version>1.1</version>  
  16.                         <configuration>  
  17.                             <!-- 配置项目自动发布服务器 -->  
  18.                             <url>http://xx.xx.xx.xx:8080/manager/text</url>  
  19.                             <path>/xmj-manager</path>  
  20.                             <server>Tomcat</server>  
  21.                             <warFile>target/${profiles.activation}.war</warFile>  
  22.                         </configuration>  
  23.                     </plugin>  
  24.                 </plugins>  
  25.             </build>  
  26.         </profile>  
  27.         <profile>  
  28.             <id>xmj_new</id>  
  29.             <properties>  
  30.                 <profiles.activation>xmj_new</profiles.activation>  
  31.             </properties>  
  32.             <build>  
  33.                 <plugins>  
  34.                     <plugin>  
  35.                         <groupId>org.codehaus.mojo</groupId>  
  36.                         <artifactId>tomcat-maven-plugin</artifactId>  
  37.                         <version>1.1</version>  
  38.                         <configuration>  
  39.                             <!-- 配置项目自动发布服务器 -->  
  40.                             <url>http://xx2.xx.xx.xx:8080/manager/text</url>  
  41.                             <path>/xmj-manager</path>  
  42.                             <server>Tomcat</server>  
  43.                             <warFile>target/${profiles.activation}.war</warFile>  
  44.                         </configuration>  
  45.                     </plugin>  
  46.                 </plugins>  
  47.             </build>  
  48.         </profile>  
  49. ...  
  50. ...  
  51. ...  
  52. </profiles>  



activeByDefault标签配置true表示默认**的环境,直接install就是使用此配置的环境。 
这里有一个自定义属性配置:profiles.activation 它就是整合Maven profile 和spring profile 的重要配置 

整合Maven profile 和spring profile 

通过Maven管理web实现自动化,少改动就少出错,将上面web.xml配置改为下面的: 

Xml代码 

 Maven 整合 spring profile实现多环境自动切换

  1. <context-param>  
  2.         <param-name>spring.profiles.active</param-name>  
  3.         <param-value>${profiles.activation}</param-value>  
  4. </context-param>  



这还不算完,还要配置Maven的一个插件: 

Xml代码 

 Maven 整合 spring profile实现多环境自动切换

  1. <plugin>  
  2.                 <groupId>org.apache.maven.plugins</groupId>  
  3.                 <artifactId>maven-war-plugin</artifactId>  
  4.                 <configuration>  
  5.                     <warName>${profiles.activation}</warName>  
  6.                     <!-- **spring profile -->  
  7.                     <webResources>  
  8.                         <resource>  
  9.                             <filtering>true</filtering>  
  10.                             <directory>src/main/webapp</directory>  
  11.                             <includes>  
  12.                                 <include>**/web.xml</include>  
  13.                             </includes>  
  14.                         </resource>  
  15.                     </webResources>  
  16.                     <warSourceDirectory>src/main/webapp</warSourceDirectory>  
  17.                     <webXml>src/main/webapp/WEB-INF/web.xml</webXml>  
  18.                 </configuration>  
  19. </plugin>  



打包的时候Maven会去自动修改web.xml文件,根据占位符自动替换为对应的属性值 
warName标签可以不配置,我这里加上了所以需要加上前面的target/${profiles.activation}.war,否则会报找不到war包的异常。 

执行profile 
下面是见证奇迹的时刻 
在eclipse中执行命令: 

Java代码 

 Maven 整合 spring profile实现多环境自动切换

  1. clean install  


前面配置的默认环境是xmj_old这个,在执行完命令之后target文件夹下面出现了一个名为xmj_old.war的war包 

Maven 整合 spring profile实现多环境自动切换 

打开war包查看web.xml 

Maven 整合 spring profile实现多环境自动切换 

再测试下切换到其他的环境 
执行命令 

Java代码 

 Maven 整合 spring profile实现多环境自动切换

  1. clean install -P xmj_new  


-P 参数后面加上profile的id即可完成自动切换,执行完之后看下是否已经自动切换到id为xmj_new的profile环境下 
target文件下有了xmj_new.war的war包(xmj_old.war被clean掉了) 

Maven 整合 spring profile实现多环境自动切换 

打开war包查看web.xml文件 

Maven 整合 spring profile实现多环境自动切换 

如预期所料,Maven结合spring成功的完成了多环境的自动切换 
注:上面web.xml中的display-name和webAppRootKey都是使用占位符${profiles.activation}然后Maven自动替换的,如果你的项目中使用log4j/logback和spring,然后同一个项目部署多个实例到一个tomcat中,建议配置webAppRootKey这个参数 
请参考 log4j/logback + spring的webRootKey bug 

在本地eclipse内置tomcat中运行 

由于内置tomcat是直接编译源码然后放到指定的位置去加载 
所以上述的方法对于在内置tomcat运行是行不通的,在本地测试就非常蛋疼了 
网上说有设置项目属性中Maven的profile,查了下eclipse官网说是由于m2eclipse有bug的问题,这个配置已经给禁用了 
那就要另觅他法了,下面介绍一种探索出的一个方法: 

首先在main目录下新建一个profile文件夹,将WEB-INF下面的web.xml复制过来一份 
然后将WEB-INF下面的web.xml中的占位符修改成默认的配置(即没有占位符的,在本地测试用的profile值) 
profile文件夹下保留占位符的web.xml配置 

Maven 整合 spring profile实现多环境自动切换 

下面是WEB-INF下面没有占位符的正常的配置 

Maven 整合 spring profile实现多环境自动切换 

这些占位符我都换成了ysxj 
接下来修改Maven配置 
将配置: 

Xml代码 

 Maven 整合 spring profile实现多环境自动切换

  1. <plugin>  
  2.                 <groupId>org.apache.maven.plugins</groupId>  
  3.                 <artifactId>maven-war-plugin</artifactId>  
  4.                 <configuration>  
  5.                     <warName>${profiles.activation}</warName>  
  6.                     <!-- **spring profile -->  
  7.                     <webResources>  
  8.                         <resource>  
  9.                             <filtering>true</filtering>  
  10.                             <directory>src/main/webapp</directory>  
  11.                             <includes>  
  12.                                 <include>**/web.xml</include>  
  13.                             </includes>  
  14.                         </resource>  
  15.                     </webResources>  
  16.                     <warSourceDirectory>src/main/webapp</warSourceDirectory>  
  17.                     <webXml>src/main/webapp/WEB-INF/web.xml</webXml>  
  18.                 </configuration>  
  19.             </plugin>  


修改为:

Xml代码 

 Maven 整合 spring profile实现多环境自动切换

  1. <plugin>  
  2.                 <groupId>org.apache.maven.plugins</groupId>  
  3.                 <artifactId>maven-war-plugin</artifactId>  
  4.                 <configuration>  
  5.                     <warName>${profiles.activation}</warName>  
  6.                     <!-- **spring profile -->  
  7.                     <webResources>  
  8.                         <resource>  
  9.                             <filtering>true</filtering>  
  10.                                 <!-- 这里是刚刚创建的目录 -->  
  11.                             <directory>src/main/profile</directory>  
  12.                                 <!-- 目标目录为WEB-INF -->  
  13.                             <targetPath>WEB-INF</targetPath>  
  14.                             <includes>  
  15.                                 <include>**/web.xml</include>  
  16.                             </includes>  
  17.                         </resource>  
  18.                     </webResources>  
  19.                     <warSourceDirectory>src/main/webapp</warSourceDirectory>  
  20.                     <webXml>src/main/webapp/WEB-INF/web.xml</webXml>  
  21.                 </configuration>  
  22.             </plugin>  


最后见证奇迹 
执行命令 

Java代码 

 Maven 整合 spring profile实现多环境自动切换

  1. install -P naruto  


在target下面出现根据profile打的war包naruto.war 
接下来证明可以在eclipse的内置tomcat使用 
执行命令 

Java代码 

 Maven 整合 spring profile实现多环境自动切换

  1. eclipse:eclipse  -Dwtpversion=1.5  


编译成正常的eclipse工程,然后加入tomcat服务器,你会发现能运行成功。 
这里tomcat使用的是源码中WEB-INF下的web.xml,即刚才将占位符修改为ysxj的那个web.xml 
其原理就是在编译阶段将profile文件夹下的web.xml中的占位符替换成Maven中配置的属性,然后覆盖WEB-INF下面的web.xml 
这种方法麻烦的一点就是如果web.xml文件有修改 ,两个记得要同步,一般情况下这个文件也极少动