2011-05-11 79 views
10

我有几次遇到同样的问题,我想对其他人对此问题的看法有所了解: 假设我们将Spring应用程序打包为.war文件,我们想运行它在几个环境。 (开发/测试/ preprod/prod /等)在Spring Web应用程序中处理配置文件

为了访问应用程序所需的基础架构(数据库/ web服务等),我们将访问信息存储在配置文件中,同时一些业务配置也在这些文件中。 假设我们使用.properties文件(因为我们在战争中有一个弹簧应用程序,并且我们喜欢通过appcontext中的一行代码读取属性) 并且还假设在不同的环境中我们不会没有相同的appserver/servlet容器。 (例如:开发,测试:码头,preprod:tomcat的,PROD:GlassFish的)

我通常做的是创建多个Maven的型材,每个环境,每个相应的文件所需的配置。

现在最近我遇到了一个运行操作的人的问题: '如果在preprod环境中更改了数据库,那么我们真的必须在buildserver上生成具有适当配置文件的新版本? 我回答'不,你可以真正去....../webapps/currentApp/WEB-INF/classes/config/application.properties并在那里更改值,然后重新启动容器'

我们想出了一个解决这个问题的一些方面的解决方案: 使用Maven汇编插件我们在里面嵌入了一个Jetty 这个战争使得它可以用作'可执行的'战争,同时也使我们有可能拥有一个全局配置XML, 嵌入式Jetty的入门者在分解的war目录中创建/修改适当的.properties文件,然后才启动应用程序。

但是,如果您想使用除Jetty以外的其他任何内容,这也不能解决问题。

大家怎么处理同样的情况?

回答

9

环境变量,外部配置文件

我们有类似的东西,一个Web应用程序在Tomcat中/ Weblogic的运行与春天。 我们所做的是定义一个environment property CONFIG_PATH,并将所有XML(包括spring config)和属性文件放在该目录中。

我们有多个属性文件(每个环境),我们将其作为tar文件发送。 Web应用程序从CONFIG_PATH目录加载所有Properties/Spring配置文件。此变量在相应环境中定义为环境变量

这样我们就不会触及WAR文件,也不会为环境构建单独的WAR。想想这个场景的:内置QA & PROD WAR文件,QA测试,QA战争的文件,部署在PROD但一些PROD WAR炸毁:(

我们做如下事情:

在Spring配置XML,我们定义:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="order" value="0"></property> 
    <property name="locations"> 
     <list> 
      <value>file:${CONFIG_PATH}/App.properties</value> 
     </list> 
    </property> 
</bean> 

参见所有变量和往常一样在Spring配置

在web.xml中,我们定义如下Spring配置:

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener 
    </listener-class> 
</listener> 

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>file:${CONFIG_PATH}/**/spring-config.xml 
    </param-value> 
</context-param> 

QA/PROD团队使用相应的环境文件部署相同的工件。如果事情爆发,我们只知道它的环境。属性搞砸了。 HTH

+0

感谢你的回答,有趣的方法,看起来像值得一试。 – abalogh 2011-05-12 10:13:33

4

数据库

开发商不能碰WAR一旦它去,我的工作环境,所以如果我们需要改变配置值,而无需重新部署我们把它放在一个关系数据库。

那些不需要重新包装,重新部署或退回服务器。但是,应用程序不得不定期刷新只读配置。

JNDI

JNDI设置保持从环境到环境固定;这些更改由应用服务器管理员设置一次,不会更改。 (请参阅Oracle Tutorial

我正在讨论应用程序自身配置的名称/值对,而不是JNDI。

+0

保持配置在数据库中是一个好主意,感谢您的输入。但是后来我失去了自动读取.properties文件,我必须在加载spring上下文后手动加载它们。 (或者拿出一个类似PropertyPlaceholderConfigurer的自己的实现,它使用数据库) – abalogh 2011-05-11 16:47:52

2

对于数据源;在tomcat上下文中创建一个JNDI资源条目并将你的资源条目/配置从应用程序中分离出来是一种常见的方法。如果DB已更改,则可以重新配置容器中的JNDI资源(Tomcat,Jetty等)并重新启动。如果你有一个容器场,那么重启你的tomcat实例将不会有问题。您可以在负载平衡器上停用它们,然后重新启动。我认为在Jetty中还有一个上下文文件,您可以在其中添加JNDI资源。此外,还有一些取决于不同背景的属性的配置文件。您可以使用maven的“-P”参数选择您的配置文件,并且您的项目将使用这些配置进行构建,例如针对不同的目标环境,例如实况和测试。

相关问题