基于 Spring 的 Web 应用程序的环境特定配置?

Posted

技术标签:

【中文标题】基于 Spring 的 Web 应用程序的环境特定配置?【英文标题】:Environment-specific configuration for a Spring-based web application? 【发布时间】:2011-09-11 04:50:07 【问题描述】:

我如何知道 Web 应用程序的部署环境,例如无论是本地、dev、qa 还是 prod 等。有什么方法可以在运行时在 spring 应用程序上下文文件中确定这一点?

【问题讨论】:

【参考方案1】:

值得注意的是Spring 3.1 M1 introduced profiles support。这可能是这种需求的最终答案。所以请留意它。

与此同时,我个人完全按照 Pavel 的描述行事。

【讨论】:

【参考方案2】:

不要在你的代码中添加逻辑来测试你在哪个环境中运行——那是灾难的根源(或者至少在路上烧了很多午夜的油)。

您使用 Spring,因此请充分利用它。使用依赖注入为您的代码提供特定于环境的参数。例如。如果您需要在测试和生产中调用具有不同端点的 Web 服务,请执行以下操作:

public class ServiceFacade 
    private String endpoint;

    public void setEndpoint(String endpoint) 
        this.endpoint = endpoint;
    

    public void doStuffWithWebService() 
        // use the value of endpoint to construct client
    

接下来,使用 Spring 的 PropertyPlaceholderConfigurer(或 PropertyOverrideConfigurer)从 .properties 文件或 JVM 系统属性中填充此属性,如下所示:

<bean id="serviceFacade" class="ServiceFacade">
    <property name="endpoint" value="$env.endpoint"/>
</bean>

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <value>classpath:environment.properties</value>
    </property>
</bean>

现在像这样创建两个(或三个,或四个)文件 - 为每个不同的环境创建一个。

在 environment-dev.properties 中:

env.endpoint=http://dev-server:8080/

在 environment-test.properties 中:

env.endpoint=http://test-server:8080/

现在为每个环境获取适当的属性文件,将其重命名为 environment.properties,然后将其复制到应用服务器的 lib 目录或应用程序类路径中的其他位置。例如。对于 Tomcat:

cp environment-dev.properties $CATALINA_HOME/lib/environment.properties

现在部署您的应用程序 - Spring 在运行时设置您的端点属性时将替换值“http://dev-server:8080/”。

有关如何加载属性值的更多详细信息,请参阅 Spring 文档。

【讨论】:

感谢您的快速回复。您使用的示例是我正在处理的示例。我正在做的是,创建了一个类,构造函数具有参数端点和客户端代理。在 appcontext.xml 中,根据环境传递端点,使用映射,例如 很好的答案!我只有一个后续问题。 lib 文件夹不是为库制作的吗?是不是有不同的位置可以从类路径访问,比如conf什么的?谢谢! 再做一些研究,我认为lib文件夹实际上是the worst place to put configuration 这不是最好的选择,而且不仅仅适用于 Tomcat。我最近一直在研究 ZooKeeper(请参阅:***.com/questions/9940476/…),但在 Spring / JavaEE 引入对动态属性的支持之前,大多数解决方案总是有点麻烦。【参考方案3】:

一种方法是查看System.getProperty(key) 方法,它是纯java。但是,这可能不是一个好主意,因为您实际上不应该在应用程序中执行此类环境逻辑。

另一种方法是服务器配置(为每个环境的服务器配置不同的应用程序上下文文件)。

Spring 3.1 还引入了新的方法来“正确”地使用可互换的属性文件来完成这类事情。你应该看看unified property management blog。 m1 release announcement有更多细节。

【讨论】:

【参考方案4】:

我们在我们的应用程序中执行此操作,而不是在 spring 配置中。

在应用程序启动期间(在上下文侦听器中),我们读取机器的主机名并将匹配的 prod、dev、qa 信息存储在静态变量中。

我们不直接访问该变量(虽然可以),但我们有一个与该变量交互的 spring 服务,让我们可以访问我们的服务器环境信息。

【讨论】:

以上是关于基于 Spring 的 Web 应用程序的环境特定配置?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security 和自定义外部身份验证

如何使用 Spring Security 处理基于用户权限的授权?

如何在 Spring 中以编程方式解析属性占位符

Spring基础入门

Spring基础入门

Spring Boot 环境特定的配置