【问题标题】:Set default properties in a library with spring-boot使用 spring-boot 在库中设置默认属性
【发布时间】:2015-05-07 17:07:23
【问题描述】:

我有许多使用 spring-boot 的不同服务。我想为每个服务设置一些通用的配置,但允许服务拥有自己的属性并在需要时覆盖它们。示例属性包括 spring.show_banner、管理 url 等。

我该怎么做?如果我有以下情况:

  • 带有默认属性的 src/main/resources/application.yml 的服务通用
  • 带有 src/main/resources/application.yml 的 service1 和它自己的属性

我希望它们优先与 service1 版本合并。相反,似乎只使用了在类路径中找到的第一个。

(或者,使用@Configuration 类会更好,但我不确定它们是否可以用于定义许多属性)

【问题讨论】:

    标签: java spring spring-boot


    【解决方案1】:

    您可以使用多个选项,所有选项都基于order in which property sources are considered

    如果您的公共库负责创建SpringApplication,它可以使用setDefaultProperties。这些值可以被您的服务的application.properties 覆盖。

    或者,您的库可以在其 @Configuration 类之一上使用 @PropertySource 来配置,例如,library.properties 作为源。同样,这些属性随后可以在您的服务的application.properties 中被覆盖。

    【讨论】:

    • 谢谢安迪。你的第二种方法对我有用。我假设默认的 spring-boot 将具有 classpath*/application.yml 的属性源(带有星号以查找多个匹配项);但我想这可能会带来问题。
    • 我尝试了这种方法,似乎它不适用于所有属性。例如,spring.main.banner-mode=off 似乎不起作用。而其他属性都很好。我假设某些属性在启动阶段使用得太早以至于无法通过外部库中的 PropertySource 设置它们?这种理解是否正确?如果正确,设置这些属性的唯一方法是什么?哪些属性会受到影响?
    • 而另一个属性“spring.output.ansi.enabled”似乎仅在通过命令行属性传递并将其添加到 application.yml 时才有效,但当它是默认属性的一部分时则无效.这真的很令人困惑,因为这些设置是否有效,取决于它们的指定方式。
    • 这仅适用于 .properties 文件,not for .yml files
    • 如果我使用 library.properties 走这条路 --> 是否也可以指定环境特定的库属性?那么如果消费应用程序正在运行application-stage.properties,有没有一种简单的方法来选择library-stage.properties?
    【解决方案2】:

    我不确定你所说的合并它们是什么意思。

    但我假设您最终描述的是您具有特定于配置文件的配置的情况。因为,任何特定于特定服务的属性都可以使用 Spring 配置文件进行管理/注入,它将始终优先于默认属性文件(请参阅documentation)。

    例如,您可以拥有文件 application-service1.properties,当您使用属性 spring.profiles.active=service1 运行应用程序时,该文件会自动使用,可以在命令行和other的地方指定。 如果不指定此属性,Spring Boot 将回退到默认的 application.properties 文件。

    当然你也可以在两个文件中写下共同的属性:

    application.properties

    service.url=http://localhost:8080/endpoint
    service.user=admin
    service.password=admin
    

    application-service1.properties

    service.url=http://api.service.com/endpoint
    service.user=admin
    service.password=aosdnoni3
    

    希望这会有所帮助。

    抱歉格式不好,我对编辑器还是不熟悉。

    【讨论】:

      【解决方案3】:
      public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {
          @Override
          public void onApplicationEvent(ApplicationEvent event) {
              if (event instanceof ApplicationEnvironmentPreparedEvent) {
                  ApplicationEnvironmentPreparedEvent envEvent = (ApplicationEnvironmentPreparedEvent) event;
                  ConfigurableEnvironment env = envEvent.getEnvironment();
                  Properties props = new Properties();
                  //set props as desired
                  env.getPropertySources()
                          .addFirst(new PropertiesPropertySource("customname", props));
          }
      }
      

      然后在 src/main/resources/META-INF/spring.factories 中,添加一行: org.springframework.context.ApplicationListener=mypackage.MyApplicationListener

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-16
        • 1970-01-01
        • 1970-01-01
        • 2020-08-21
        • 1970-01-01
        • 2018-10-31
        • 1970-01-01
        相关资源
        最近更新 更多