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

Posted

技术标签:

【中文标题】如何在 Spring 的 Tomcat Web 服务器中外部化 application.properties?【英文标题】:How to externalize application.properties in Tomcat webserver for Spring? 【发布时间】:2017-05-18 14:58:36 【问题描述】:

SpringApplication 将从 application.properties 加载属性 在以下位置创建文件并将它们添加到 Spring 环境:

- 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

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

自定义位置应优先于上述位置。

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

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

【问题讨论】:

您是否尝试过将application.propeties 放在 Tomcat 类路径中? 但是,如果我有多个 war 文件,并且每个文件都有一个 application.properties,我会将它们放在哪里,而不会相互覆盖? 您可以在启动 jar 时提供外部文件位置。 java -jar myproject.jar -spring.config.location=D:/application.properties 【参考方案1】:

使用Tomcat9.0.27

运行 Spring boot 2.2.1

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

export spring_config_location=/<PATH_TO_CONF_DIR>/application.properties

并让它工作..

【讨论】:

【参考方案2】:

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

export SPRING_PROFILES_ACTIVE=dev

【讨论】:

【参考方案3】:

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

#!/bin/bash

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

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

【讨论】:

【参考方案4】:

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

 export spring_config_location=/<YOUR_PATH>/application.properties

示例:

 export spring_config_location=/app/conf/application.properties

【讨论】:

【参考方案5】:

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

对于 Tomcat,您可以通过将以下行添加到您的 &lt;TOMCAT_HOME&gt;/bin/setenv.sh 文件中来执行此操作(如果缺少则创建该文件):

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

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

@SpringBootApplication
public class MyApplication 

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

这将在使用 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");
    


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

更新

Spring Boot 2 以来,spring_config_location 的行为发生了变化(来自 migration guide):

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

因此,根据您的用例,您应该考虑将哪些属性设置为环境变量。新的应该在setenv.sh 中看起来像spring_config_additional-location。 reference documentation 中也描述了从哪里查找文件。

【讨论】:

使用这个我无法生成战争文件。 您使用的是哪个版本的 Spring Boot / Spring?自 Boot 2 以来,他们改变了“spring_config_location”的行为。我也更新了我的答案以涵盖最新版本。如果不是这种情况,你会得到什么错误? 嗨,我正在使用 Spring Boot 2,我正在尝试使用“spring_config_additional-location”作为环境变量,但 spring 无法识别它。我创建的变量的名称是“SPRING_CONFIG_ADDITIONAL_LOCATION”,但似乎 spring 在启动时并没有处理它。在 Linux 操作系统中设置此变量 spring_config_additional-location 的正确方法是什么? 在 ADDITIONAL 和 LOCATION 之间,而不是下划线 ("_") 应该是连字符 ("-")。所以变量应该命名为 SPRING_CONFIG_ADDITIONAL-LOCATION。大写和小写都可以。 对于 Windows 机器,该文件将是一个批处理文件/bin/setenv.bat 并且导出将被替换为 Set【参考方案6】:

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

spring.config.additional-location=/etc/tomcat/&lt;appname&gt;/application-production.properties

【讨论】:

【参考方案7】:

对我来说,最简单的方法是在 Tomcat 的配置文件夹中放置一个上下文文件。例如,如果您的应用程序在根路径下运行(例如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>

【讨论】:

【参考方案8】:

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

然后,在目录中放置您想要外部化的资源,一切都会运行良好。要在 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>

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

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

【讨论】:

以上是关于如何在 Spring 的 Tomcat Web 服务器中外部化 application.properties?的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有完整安装 Tomcat 的情况下运行 Spring Web 应用程序?

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

如何在嵌入式 tomcat 服务器上部署 Spring Boot Web 应用程序,来自 Spring Boot 本身

在单个 Tomcat 服务器中部署多个 Spring Boot 应用程序意味着显示异常。如何解决这个问题?

关于如何将我的spring boot web应用部署到tomcat8的一个问题

从设计模式+源码讲到Tomcat加载Spring,你还不懂?