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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6284745/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 15:12:21  来源:igfitidea点击:

Environment-specific configuration for a Spring-based web application?

javaspringdeploymentspring-mvcjakarta-ee

提问by Ritesh Mengji

How can I know the deployment environment of a web application, e.g. whether it is local, dev, qa or prod, etc. Is there any way I can determine this in spring application context file at runtime?

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

回答by Pavel

Don't add logic to your code to test which environment you're running in - that is a recipe for disaster (or at least burning a lot of midnight oil down the road).

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

You use Spring, so take advantage of it. Use dependency injection to provide environment-specific parameters to your code. E.g. if you need to call a web service with different endpoints in test and production, do something like this:

您使用 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
    }
}

Next, use Spring's PropertyPlaceholderConfigurer(or alternatively PropertyOverrideConfigurer) to populate this property from either a .properties file, or from a JVM system property like so:

接下来,使用 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>

Now create two (or three, or four) files like so - one for each of the different environments.

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

In environment-dev.properties:

在 environment-dev.properties 中:

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

In environment-test.properties:

在 environment-test.properties 中:

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

Now take the appropriate properties file for each environment, rename it to just environment.properties, and copy it to your app server's lib directory or somewhere else where it will appear on your app's classpath. E.g. for Tomcat:

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

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

Now deploy your app - Spring will substitute the value "http://dev-server:8080/" when it sets up your endpoint property at runtime.

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

See the Spring docs for more details on how to load the property values.

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

回答by Amr Mostafa

It's worth noting that Spring 3.1 M1 introduced profiles support. Which will probably be the ultimate answer to this need. So keep an eye for it.

值得注意的是,Spring 3.1 M1 引入了配置文件支持。这可能是对这种需求的最终答案。所以要留意它。

Meanwhile, I personally do exactly what Pavel described.

与此同时,我个人完全按照 Pavel 所描述的去做。

回答by joekarl

We do this in our application but not within the spring config.

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

During app startup (in a context listener) we read the machine's hostname and store the matching prod,dev,qa info in a static variable.

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

We don't access the variable directly (though one could) but we have a spring service that interfaces with that variable to give us access to our server environment information.

我们不直接访问该变量(尽管可以)但我们有一个与该变量接口的 spring 服务,以便我们访问我们的服务器环境信息。

回答by Simon Elliston Ball

One way would be to look at the System.getProperty(key)method, which is pure java. However, this is probably not a great idea since you shouldn't really be doing environment logic of this sort in your application.

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

Another method would be server configuration (configure a different application context file for each environment's server).

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

Spring 3.1 is also bringing in new methods to do this sort of thing 'properly' with interchangeable property files. You should take a look at the unified property management blog. There is more detail in the m1 release announcement.

Spring 3.1 还引入了新方法,可以使用可互换的属性文件“正确”执行此类操作。你应该看看统一物业管理博客m1 发布公告中有更多详细信息。