Spring 使用外部配置在 Tomcat 上启动

Spring boot on Tomcat with external configuration

我在 Whosebug 上找不到这个问题的答案,所以我在这里提问,这样我就可以得到一些想法。

我有一个 Spring 启动应用程序,我已将其作为 war 程序包部署在 Tomcat 8 上。我遵循了本指南 Create a deployable war file,它似乎工作得很好.

然而,我目前遇到的问题是能够将配置外部化,以便我可以将配置作为人偶模板进行管理。

在我的项目中,

src/main/resources
                  -- config/application.yml
                  -- config/application.dev.yml
                  -- config/application.prod.yml
                  -- logback-spring.yml

那么我怎样才能在外部加载 config/application.dev.ymlconfig/application.prod.yml 并仍然保留 config/application.yml 呢? (包含默认属性,包括 spring.application.name

我读到配置是按这个顺序加载的,

  1. 当前目录的/config 子目录。
  2. 当前目录
  3. 类路径/配置包
  4. 类路径根目录

因此我尝试从 /opt/apache-tomcat/lib 加载配置文件但无济于事。

目前有效的方法

正在通过 export CATALINA_OPTS="-Dspring.config.location=/opt/apache-tomcat/lib/application.dev.yml"

加载

不过我想知道的是,

  1. 了解为什么无法通过 /opt/apache-tomcat/lib 类路径加载。
  2. 有没有更好的方法来实现这个目标?

您对加载顺序的看法是正确的。根据Spring boot documentation

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).

[Note]
You can also use YAML ('.yml') files as an alternative to '.properties'.

这意味着,如果您将 application.yml 文件放置到 /opt/apache-tomcat/lib/opt/apache-tomcat/lib/config,它将被加载。

  1. Find out why loading via /opt/apache-tomcat/lib classpath doesn't work.

但是,如果您将 application.dev.yml 放置到该路径,它将不会被加载,因为 application.dev.yml 不是 Spring 正在查找的文件名。如果您希望 Spring 也读取该文件,则需要将其作为选项提供
--spring.config.name=application.dev-Dspring.config.name=application.dev.
但我不建议使用这种方法

  1. And is there a better method to achieve this ?

是的。使用 Spring profile-specific properties。您可以将文件从 application.dev.yml 重命名为 application-dev.yml,并提供 -Dspring.profiles.active=dev 选项。 Spring 将读取 application-dev.ymlapplication.yml 文件,配置文件特定配置将覆盖默认配置。

我建议在每个相应的 server/tomcat 实例上添加 -Dspring.profiles.active=dev(或 prodto CATALINA_OPTS

    I have finally simplified solution for reading custom properties from external location i.e outside of the spring boot project. Please refer to below steps.
Note: This Solution created and executed windows.Few commands and folders naming convention may vary if you are deploying application on other operating system like Linux..etc.

         1. Create a folder in suitable drive.
         eg: D:/boot-ext-config

         2. Create a .properties file in above created folder  with relevant property key/values and name it as you wish.I created dev.properties for testing purpose.
         eg :D:/boot-ext-config/dev.properties

            sample values:
            dev.hostname=www.example.com


        3. Create a java class in your application as below
        ------------------------------------------------------
        import org.springframework.boot.context.properties.ConfigurationProperties;
        import org.springframework.context.annotation.PropertySource;

        @PropertySource("classpath:dev.properties")
        @ConfigurationProperties("dev")
        public class ConfigProperties {
            private String hostname;

            //setters and getters
        }
        --------------------------------------------
         4. Add @EnableConfigurationProperties(ConfigProperties.class) to SpringBootApplication as below
        --------------------------------------------
        @SpringBootApplication
        @EnableConfigurationProperties(ConfigProperties.class)
        public class RestClientApplication {
            public static void main(String[] args)  {
                 SpringApplication.run(RestClientApplication.class, args);
        }
        }
        ---------------------------------------------------------
        5. In Controller classes we can inject the instance using @Autowired and fetch properties

        @Autowired
            private ConfigProperties configProperties;

        and access properties using getter method 
       System.out.println("**********hostName******+configProperties.getHostName());

Build your  spring boot maven project and run the below command to start application.

-> set SPRING_CONFIG_LOCATION=<path to your properties file>

->java -jar app-name.jar