【问题标题】:Overriding @ConfigurationProperties覆盖@ConfigurationProperties
【发布时间】:2016-05-13 19:54:32
【问题描述】:

我正在开发一个 Spring Integration/Boot 应用程序。我正在使用多文档application.yml (src/main/resources/application.yml) 为多个配置类设置默认值(用@ConfigurationProperties 注释)。 Applicaiton.yml 带有默认值,其中一些需要被覆盖,具体取决于环境。

我愿意使用 Java 系统属性(-D...=...)、Spring“属性”(--...=...),或者最好使用位于 Jar 外部的 yaml 文件, 在一个目录中。

Application.yml 有 4 个文档,每个文档对应一个不同的配置类。让我们只关注 ServerConfig:

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(locations = "classpath:application.yml", prefix = "server")
public class ServerConfig {
    private Integer port;
    private String address;

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

Application.yml:

server:
  address: ::1
  port: 8080

---

注意我是如何在注释中指定locations 的。这会加载 application.yml 并成功使用这些值,但我不知道如何覆盖它们(比如 -Dserver.port=7777 或 --server.port=7777)。如果我删除 locations = ...,那么我可以使用 `-Dserver.port=7777,但 application.yml 中的默认值永远不会加载,所以我必须将每个值指定为命令行参数。

我已经阅读了很多遍https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html,但我不明白为什么我不能将locations = 'application.yml' 留在配置注释中并选择性地用系统属性覆盖。

有人知道怎么做吗?

【问题讨论】:

  • 为什么要用自己的类替换内置的服务器属性? github.com/spring-projects/spring-boot/blob/v1.3.5.RELEASE/… 可能冲突了
  • @zapl:我什至不知道它存在,但我认为它不适用于 Spring Integration 或 servlet 之外。无论如何,我有 3 个用于特定于应用程序配置的配置类,它们遇到了完全相同的问题。这只是人们最容易理解的。
  • 糟糕,这只是 spring-boot-web 的一部分。会不会是github.com/spring-projects/spring-boot/issues/5111?换句话说,location 不应该被使用,但它应该可以在没有它的情况下工作。
  • 我正在阅读同一个线程。 locations 的行为令人惊讶,老实说,糟糕的设计。话虽如此,如果我不指定位置,则不会加载任何内容,并且最终我的代码会遇到异常,因为配置 getter 返回 null。我正在使用弹簧配置文件处理application.yaml,并切换到每个配置文件使用 yaml 文档。不幸的是,除非我把它放在locations 中,否则spring 拒绝加载application.yaml。我已经完成了两个教程,但我无法弄清楚为什么 spring 会加载他们的 application.yaml 但不会触及我的。
  • 也许.. config 属性 bean 是 @Component 不是配置

标签: java spring spring-boot spring-integration


【解决方案1】:

叹息。这是应用程序启动的问题——由于我在 Spring Integration 和 Spring Boot 之间的混淆造成的。

我的主要方法曾经是:

 @SpringBootApplication
 public class Main {
     public static void main(String... args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext("org.fandingo.blah.blah");
        ctx.registerShutdownHook();
 }

我的理解是,这就是你如何启动一个仅是 Spring 集成的应用程序(当然假设是 JavaConfig)。问题是 YAML 属性加载是 Spring Boot 功能。切换 main 方法以使用 Spring Boot 方法解决了问题:

 @SpringBootApplication
public class Main {
    public static void main(String... args) {
        SpringApplication app = new SpringApplication(Main.class);
        app.setRegisterShutdownHook(true);
        app.run(args);
    }
}

春天是如此的复杂和神秘。为什么 Spring Integration 和 Boot 不能自然合作,我想不通。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 2012-01-28
    • 2012-02-16
    • 1970-01-01
    • 1970-01-01
    • 2021-06-26
    • 2020-06-06
    相关资源
    最近更新 更多