Java 如何在 Spring 的 Tomcat Web 服务器中外部化 application.properties?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41461786/
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-08-11 23:23:25  来源:igfitidea点击:

How to externalize application.properties in Tomcat webserver for Spring?

javaspringtomcatspring-boot

提问by membersound

SpringApplication will load properties from application.properties files in the following locations and add them to the Spring Environment:

- A /config subdirectory of the current directory.
- The current directory
- A classpath /config package
- The classpath root

The list is ordered by precedence (properties defined in locations higher in the list override those defined in lower locations).

SpringApplication 将从以下位置的 application.properties 文件加载属性并将它们添加到 Spring Environment:

- A /config subdirectory of the current directory.
- The current directory
- A classpath /config package
- The classpath root

该列表按优先级排序(在列表中较高位置定义的属性覆盖在较低位置定义的属性)。

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-application-property-files

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-application-property-files

Question: when running a warfile on a tomcatserver: how can I add an additional location for the application.propertiesoutsidethe classpath or the tomcat container, like d:\application.properties?

问题:在服务器war上运行文件时tomcat:如何为类路径或 tomcat 容器的application.properties外部添加额外的位置,例如d:\application.properties

The custom location should get highest precedence regarding the locations above.

自定义位置应获得有关上述位置的最高优先级。

Problem is: I could of course add a /configfolder inside my exploded war in the tomcat webappsfolder, but then I'd lose any custom configuration if the webapps folder is cleaned and war is redeployed.

问题是:我当然可以/config在 tomcatwebapps文件夹中的爆炸战争中添加一个文件夹,但是如果清除 webapps 文件夹并重新部署战争,我将丢失任何自定义配置。

Thus I'd like to add an additional location outside.

因此,我想在外面添加一个额外的位置。

回答by jlumietu

I had to do it several times and the best approach I found is to configure an external directory as classpath resource in the container:

我不得不多次这样做,我发现的最佳方法是将外部目录配置为容器中的类路径资源:

Tomcat classpath

Tomcat 类路径

Then, in the directory place the resources you want to externalize and everything will run fine. To load the resource in spring, you could do this way:

然后,在目录中放置您要外部化的资源,一切都会正常运行。要在 spring 中加载资源,您可以这样做:

<beans:bean id="externalProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <beans:property name="location" value="classpath:[my-application-name]/applicationProperties.properties" />
            <beans:property name="placeholderPrefix" value="!applicationProperties{" />
            <beans:property name="placeholderSuffix" value="}" />
        </beans:bean>

You can see that, as you said that you might want to have multiple applications deployed in each tomcat, you could simply create a directory structure in the folder you set in classpath, to maintain different application.propertiesfor each of your warapplications

可以看到,正如你所说,你可能希望在每个tomcat中部署多个应用程序,你可以简单地在你在classpath中设置的文件夹中创建一个目录结构,为你application.properties的每个war应用程序维护不同的

enter image description here

在此处输入图片说明

In case you want to maintain dinamically the application name section in your Spring configuration, you could do it in several ways, during packaging stage in maven or even using the application context path

如果你想在你的 Spring 配置中动态地维护应用程序名称部分,你可以通过多种方式来完成,在 maven 的打包阶段,甚至使用应用程序上下文路径

回答by Grzegorz B.

For me the easiest way to do it, was to place a context file inside Tomcat's config folder. For example if your application is running under root path (eg. http://your_domain.com/) you need to create a file [path_to_your_tomcat]/conf/Catalina/localhost/ROOT.xml. If your application runs in a different path, for example http://your_domain.com/example_paththe file should be named like this [path_to_your_tomcat]/conf/Catalina/localhost/example_path.xml. Inside this file you can specify a path to the external application.properties file that can be placed anywhere on your hard drive.

对我来说,最简单的方法是在 Tomcat 的 config 文件夹中放置一个上下文文件。例如,如果您的应用程序在根路径下运行(例如http://your_domain.com/),您需要创建一个文件[path_to_your_tomcat]/conf/Catalina/localhost/ROOT.xml。如果您的应用程序在不同的路径中运行,例如http://your_domain.com/example_path该文件应命名为这样[path_to_your_tomcat]/conf/Catalina/localhost/example_path.xml。在此文件中,您可以指定外部 application.properties 文件的路径,该文件可以放置在硬盘驱动器的任何位置。

<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Environment name="spring.config.location" value="file:/path/to/your/application/properties/file/" type="java.lang.String"/>
</Context>

回答by Vladimir Mitev

You can set a spring_config_locationenvironment variable pointing to the folder that contains your application.properties file.

您可以设置一个spring_config_location指向包含 application.properties 文件的文件夹的环境变量。

In the case of Tomcat you can do this by adding the following line to your <TOMCAT_HOME>/bin/setenv.shfile (create the file if missing):

在 Tomcat 的情况下,您可以通过将以下行添加到您的<TOMCAT_HOME>/bin/setenv.sh文件中来完成此操作(如果缺少则创建该文件):

export spring_config_location=/usr/local/tomcat/conf/

Place the properties file in that folder. In case you have multiple apps you can set the name of the properties file of each app to be unique. For a Spring Boot App I have done it like this:

将属性文件放在该文件夹中。如果您有多个应用程序,您可以将每个应用程序的属性文件的名称设置为唯一。对于 Spring Boot 应用程序,我是这样做的:

@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        System.setProperty("spring.config.name", "my-app");
        SpringApplication.run(MyApplication.class, args);
    }
}

This will pick the new name when run with BOOT. To have the name configured when deployed on Tomcat too, overwrite configure of SpringBootServletInitializerlike so:

这将在使用 BOOT 运行时选择新名称。要在 Tomcat 上部署时也配置名称,请SpringBootServletInitializer像这样覆盖配置:

public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MyApplication.class).properties("spring.config.name: my-app");
    }

}

Then name your properties file like: my-app.properties. Instead of the default name Spring will look for that. You can put all your apps properties files in the specified folder, /usr/local/tomcat/conf/in our sample. Your external properties will get precedence. See here for priorities: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

然后命名你的属性,如文件:my-app.properties。Spring 将查找该名称而不是默认名称。/usr/local/tomcat/conf/在我们的示例中,您可以将所有应用程序属性文件放在指定的文件夹中。您的外部属性将获得优先权。请参阅此处了解优先级:https: //docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

UPDATE

更新

Since Spring Boot 2the behavior of spring_config_locationhas changed (from the migration guide):

Spring Boot 2 开始,行为发生spring_config_location了变化(来自迁移指南):

it previously added a location to the list of default ones, now it replaces the default locations. If you were relying on the way it was handled previously, you should now use spring.config.additional-location instead.

它以前在默认位置列表中添加了一个位置,现在它替换了默认位置。如果您依赖之前的处理方式,现在应该改用 spring.config.additional-location。

So based on your use case you should consider which of the properties to set as an environment variable. The new one should look like spring_config_additional-locationin setenv.sh. Where files are looked up from is described in the reference documentationtoo.

因此,根据您的用例,您应该考虑将哪些属性设置为环境变量。新的一个看起来应该像spring_config_additional-locationsetenv.sh参考文档中也描述了从何处查找文件

回答by membersound

I finally added the following property to externalize eg secure properties:

我最终添加了以下属性来外部化例如安全属性:

spring.config.additional-location=/etc/tomcat/<appname>/application-production.properties

spring.config.additional-location=/etc/tomcat/<appname>/application-production.properties

回答by JavaSheriff

if anyone is looking for a linux solution, This is working for us:
edit tomcat startup.sh
add:

如果有人正在寻找 linux 解决方案,这对我们
有用:编辑 tomcat startup.sh
添加:

 export spring_config_location=/<YOUR_PATH>/application.properties

example:

例子:

 export spring_config_location=/app/conf/application.properties

回答by Ming M Zheng

for tomcat 9 on Ubuntu 18.04 and spring boot 2, create setenv.sh file under $CATALINA_HOME/bin/ working for me:

对于 Ubuntu 18.04 和 spring boot 2 上的 tomcat 9,在 $CATALINA_HOME/bin/ 下创建 setenv.sh 文件为我工作:

#!/bin/bash

export spring_config_additional_location="/opt/tomcat/latest/conf/application.properties"

don't forget to set file permission if needed

如果需要,不要忘记设置文件权限

回答by venkatesh akkisetty

In tomcat/bin create setenv.sh file and in file you need to give below line in file for default properties for all the wars, And save it and restart tomcat.

在 tomcat/bin 中创建 setenv.sh 文件,在文件中,您需要在文件中为所有战争的默认属性提供以下行,并保存并重新启动 tomcat。

export SPRING_PROFILES_ACTIVE=dev

回答by Amani Musomba

Using Tomcat 9.0.27

使用Tomcat 9.0.27

Running Spring boot 2.2.1

运行 Spring Boot 2.2.1

I did setup setenv.shand added the line

我做了设置setenv.sh并添加了该行

export spring_config_location=/<PATH_TO_CONF_DIR>/application.properties

and got it to work..

并让它工作..