profile主要用在项目多环境运行的情况下,比如开发环境、测试环境、线上生产环境。
我负责的项目某个数据管理后台涉及到包含测试环境在内的12个不同的运行环境,所以每次发布都很蛋疼很纠结,配置改过来改过去,到最后有些环境都忘了怎么配的。
下面以这个项目为例介绍。
准备条件:spring3.x、Maven 2
这里是整合spring的profile和Maven的profile功能
[b][size=large]spring的profile配置[/size][/b]
首先是spring的配置数据源和属性文件
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
value="jdbc:mysql://127.0.0.1:3306/db1?characterEncoding=utf8" />
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
classpath:messages_zh_CN
classpath:messages/messages_en_US-xmj_old
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
value="jdbc:mysql://127.0.0.1:3306/db1?characterEncoding=utf8" />
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
classpath:messages_zh_CN
classpath:messages/messages_en_US-xmj_new
...
...
...
这里的message_en_US-*系列属性文件是配置站点的名称和黑名单的位置:
resource.blacklist.dir=/var/resource/blacklist.txt
system.title.id=system.xmj_old.title
[b][size=large]激活spring的profile[/size][/b]
profile是配置完了,但还要激活spring的profile特性。
在web.xml做如下配置:
spring.profiles.active
xmj_old
这样就激活spring配置文件中的profile为xmj_old的配置,但这样手动配置依然要改web.xml配置。
Maven也带了profile的功能,而且我们的项目一般都是由Maven管理的,下面介绍Maven配置profile。
[b][size=large]Maven 配置profile[/size][/b]
Maven配置profile也很简单,举例如下:
xmj_old
true
xmj_old
org.codehaus.mojo
tomcat-maven-plugin
1.1
http://xx.xx.xx.xx:8080/manager/text
/xmj-manager
Tomcat
target/${profiles.activation}.war
xmj_new
xmj_new
org.codehaus.mojo
tomcat-maven-plugin
1.1
http://xx2.xx.xx.xx:8080/manager/text
/xmj-manager
Tomcat
target/${profiles.activation}.war
...
...
...
activeByDefault标签配置true表示默认激活的环境,直接install就是使用此配置的环境。
这里有一个自定义属性配置:profiles.activation 它就是整合Maven profile 和spring profile 的重要配置
[b][size=large]整合Maven profile 和spring profile[/size][/b]
通过Maven管理web实现自动化,少改动就少出错,将上面web.xml配置改为下面的:
spring.profiles.active
${profiles.activation}
这还不算完,还要配置Maven的一个插件:
org.apache.maven.plugins
maven-war-plugin
${profiles.activation}
true
src/main/webapp
**/web.xml
src/main/webapp
src/main/webapp/WEB-INF/web.xml
打包的时候Maven会去自动修改web.xml文件,根据占位符自动替换为对应的属性值
warName标签可以不配置,我这里加上了所以需要加上前面的target/${profiles.activation}.war,否则会报找不到war包的异常。
执行profile
下面是见证奇迹的时刻
在eclipse中执行命令:
clean install
前面配置的默认环境是xmj_old这个,在执行完命令之后target文件夹下面出现了一个名为xmj_old.war的war包
[img]http://dl2.iteye.com/upload/attachment/0094/9770/fbe5cfbb-fbb6-392b-8fec-415627ed8eab.jpg[/img]
打开war包查看web.xml
[img]http://dl2.iteye.com/upload/attachment/0094/9772/9f1d416e-c85d-39d9-be89-da78d9c33e38.jpg[/img]
再测试下切换到其他的环境
执行命令
clean install -P xmj_new
-P 参数后面加上profile的id即可完成自动切换,执行完之后看下是否已经自动切换到id为xmj_new的profile环境下
target文件下有了xmj_new.war的war包(xmj_old.war被clean掉了)
[img]http://dl2.iteye.com/upload/attachment/0094/9766/74a80b15-588c-3d5d-be27-5834be22ba80.jpg[/img]
打开war包查看web.xml文件
[img]http://dl2.iteye.com/upload/attachment/0094/9768/9f61ae13-d451-3ed9-aba0-37280b4827d1.jpg[/img]
如预期所料,Maven结合spring成功的完成了多环境的自动切换
注:上面web.xml中的display-name和webAppRootKey都是使用占位符${profiles.activation}然后Maven自动替换的,如果你的项目中使用log4j/logback和spring,然后同一个项目部署多个实例到一个tomcat中,建议配置webAppRootKey这个参数
请参考 [url=http://zilongsky-gmail-com.iteye.com/blog/2032070]log4j/logback + spring的webRootKey bug[/url]
[b][size=large]在本地eclipse内置tomcat中运行[/size][/b]
由于内置tomcat是直接编译源码然后放到指定的位置去加载
所以上述的方法对于在内置tomcat运行是行不通的,在本地测试就非常蛋疼了
网上说有设置项目属性中Maven的profile,查了下eclipse官网说是由于m2eclipse有bug的问题,这个配置已经给禁用了
那就要另觅他法了,下面介绍一种探索出的一个方法:
首先在main目录下新建一个profile文件夹,将WEB-INF下面的web.xml复制过来一份
然后将WEB-INF下面的web.xml中的占位符修改成默认的配置(即没有占位符的,在本地测试用的profile值)
profile文件夹下保留占位符的web.xml配置
[img]http://dl2.iteye.com/upload/attachment/0094/9764/0bc370ae-6534-38e4-ab92-824bebb70ffc.jpg[/img]
下面是WEB-INF下面没有占位符的正常的配置
[img]http://dl2.iteye.com/upload/attachment/0094/9762/f200cf90-f828-3840-adfc-24395bf84be2.jpg[/img]
这些占位符我都换成了ysxj
接下来修改Maven配置
将配置:
org.apache.maven.plugins
maven-war-plugin
${profiles.activation}
true
src/main/webapp
**/web.xml
src/main/webapp
src/main/webapp/WEB-INF/web.xml
修改为:
org.apache.maven.plugins
maven-war-plugin
${profiles.activation}
true
src/main/profile
WEB-INF
**/web.xml
src/main/webapp
src/main/webapp/WEB-INF/web.xml
最后见证奇迹
执行命令
install -P naruto
在target下面出现根据profile打的war包naruto.war
接下来证明可以在eclipse的内置tomcat使用
执行命令
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文件有修改 ,两个记得要同步,一般情况下这个文件也极少动
ps. 骚年们不要手动了,来玩自动的吧