【问题标题】:Configuring Spring based servlet with sysadmin defined properties使用系统管理员定义的属性配置基于 Spring 的 servlet
【发布时间】:2010-11-23 16:15:06
【问题描述】:

我有一个基于 Spring 的 Web 应用程序,应用程序上下文 applicationContext.xml 和 myServlet-servlet.xml 包含应该由系统管理员在部署中配置的设置。

在无需编辑 WAR 内容的情况下,启用更改 [数据库服务器详细信息、远程 Web 服务端点等] 等设置的最佳方法是什么?

Spring 提供了 PropertyPlaceholderConfigurer 可以在 bean 配置中使用,但我认为这将需要属性文件的绝对路径,我想避免这种情况,如果没有其他原因,只允许多个同一 servlet 的实例在同一台机器上运行。

也许还有使用 JNDI 配置资源的选项,但似乎没有开箱即用的 BeanFactoryPostProcessor 实现,因此它可能不是一个好方法。

处理此类要求的标准最佳实践是什么(如果有的话)?

相关的 SO 条目:

How can I specify system properties in Tomcat configuration on startup?

【问题讨论】:

    标签: java spring configuration tomcat servlets


    【解决方案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

    【讨论】:

    • 很好,实际上并不要求环境配置位于固定的根位置,/site/properties 就像 ${env.applicationRoot}/config 一样简单。我喜欢
    【解决方案2】:

    “在不需要编辑 WAR 内容的情况下,更改 [数据库服务器详细信息、远程 Web 服务端点等] 等设置的最佳方法是什么?”

    做到这一点的唯一方法是将配置外部化。您可以分解 WAR 文件,将 .properties 文件移到 WAR 之外(只要它在 CLASSPATH 中,Spring 就会找到它),或者将可修改的值放入数据库中。

    【讨论】:

    • 数据库设置是最好的方法。
    • 我不确定我是否同意将配置详细信息(例如数据库设置)放入数据库是最好的方法。有点无限递归......
    • 你必须在某个地方引导它。配置数据库可能是应用程序使用的数据库,也可能不是。
    【解决方案3】:

    如果您不想外部化您的属性文件:

    我在我的属性中使用了代表我的部署环境的前缀。示例:

    #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 来完成这个。

    【讨论】:

      猜你喜欢
      • 2011-03-21
      • 1970-01-01
      • 2011-12-02
      • 2015-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-22
      • 2017-05-23
      相关资源
      最近更新 更多