我有一个基于Spring的Web应用程序和应用程序上下文,applicationContext.xml和myServlet-servlet.xml包含应该由部署中的sysadmin配置的设置。
在不需要编辑WAR内容的情况下,更改[数据库服务器详细信息,远程Web服务端点等]设置的最佳方法是什么?
Spring提供了可以在bean配置中使用的PropertyPlaceholderConfigurer,但我认为这将需要一个绝对路径到属性文件,我想避免,如果没有其他原因,允许同一个servlet的多个实例在同一台机器上运行。
也许可以选择使用JNDI配置的资源,尽管似乎没有开箱即用的BeanFactoryPostProcessor实现,所以它可能不是一个很好的方法来接近它。
有什么标准的最佳实践(如果有的话)来处理这种要求?
相关SO条目:
How can I specify system properties in Tomcat configuration on startup?
答案 0 :(得分:1)
“在不需要编辑WAR内容的情况下,更改[数据库服务器详细信息,远程Web服务端点等]设置的最佳方法是什么?”
唯一的方法是外部化配置。您可以爆炸WAR文件,将.properties文件移到WAR之外(只要它在CLASSPATH中,Spring就会找到它),或者将可修改的值放在数据库中。
答案 1 :(得分:1)
您还可以使用基于文件的解决方案来实现此目的。在每个环境中定义环境名称系统属性。然后使用此名称加载外部属性文件。下面的示例加载一个默认集,然后使用特定于环境的集覆盖该默认集。
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="locations">
<list>
<value>classpath:site/properties/default/placeholder.properties
</value>
<value>file:///site/properties/${env.name}/placeholder.properties
</value>
</list>
</property>
</bean>
改编自我的回答here
答案 2 :(得分:0)
如果您不想外部化您的属性文件:
我在我的属性中使用了代表我的部署环境的前缀。例如:
#Test url
test.url=http://test.url.com
#Production URL
prod.url=http://prod.url.com
我在每个环境中定义了一个名为“entorn”的系统属性(在应用程序服务器启动脚本中为jvm调用的-D参数)。该属性的值在我的测试环境中是“test”,在我的生产环境中是“prod”。
然后我定义了我的“propertyConfigurer”bean:
<bean id="propertyConfigurer" class="es.indra.ccma.config.EnvironmentPropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:ccma.properties</value>
</list>
</property>
</bean>
EnvironmentPropertyPlaceholderConfigurer代码:
package es.indra.ccma.config;
import java.util.Properties;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
public class EnvironmentPropertyPlaceholderConfigurer extends
PropertyPlaceholderConfigurer {
private String environment;
final private static String ENV_SYSTEM_PROPERTY = "entorn";
public EnvironmentPropertyPlaceholderConfigurer() {
environment = System.getProperty(ENV_SYSTEM_PROPERTY);
if (environment == null) {
//default environment
environment = "test";
}
}
protected String resolvePlaceholder(String placeholder, Properties props) {
final String envPlaceholder = environment + "." + placeholder;
if (props.containsKey(envPlaceholder)) {
return props.getProperty(envPlaceholder);
} else {
return props.getProperty(placeholder);
}
}
}
如果您在“test”环境中运行代码并且想要检索“url”属性的值,则propertyConfigurer会在属性文件中查找“test.url”,如果找不到“test.url”属性它会寻找“url”属性。
这不是我的想法I followed this tutorial来完成这个。