【问题标题】:Why is @PropertySource not used when application.properties is present?为什么存在 application.properties 时不使用 @PropertySource?
【发布时间】:2018-07-09 04:21:49
【问题描述】:

我所处的情况需要将具有一些属性的文件(最终包含 ID 和电子邮件地址列表)映射到 HashMap。在 Spring 中,我发现可以使用 @ConfigurationProperties@PropertySource 将属性文件映射到对象。为了测试这种机制,我创建了一个测试项目,但是当默认的application.properties 文件存在时,@PropertySource 似乎被忽略了。我想知道这怎么可能以及如何解决它以便它使用指定的属性文件。

Application.java

@SpringBootApplication
@EnableConfigurationProperties
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

DemoProperties.java

@Component
@Configuration
@ConfigurationProperties("test")
@PropertySource("classpath:test.properties")
public class DemoProperties {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

test.properties

test.name=myNameGood

application.properties

test.name=myNameBad

ApplicationTests.java

@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {

    @Autowired
    DemoProperties demoProperties;

    @Test
    public void contextLoads() {
        System.out.println(demoProperties.getName());
    }

}

因此,当存在application.properties 时,此测试会打印myNameBad,但是当我删除或重命名该文件时,输出为myNameGood(这是所需的)。

【问题讨论】:

  • 它不会被忽略。它被覆盖。如果两者中的属性相同,则 application.properties 中的属性具有更高的优先级。尝试添加不同名称的变量并检查
  • @pvpkiran 更改变量有效,但我仍然不明白为什么它在我的示例中被覆盖。那么指定属性源有什么意义呢?
  • @ConfigurationProperties 仅适用于 Spring boot 加载的属性,即来自默认 application.properties 和朋友的属性。它不适用于使用@PropertySource 加载的属性,这些属性稍后在进程中加载​​,@ConfigurationProperties 在此之前绑定。

标签: java spring properties mapping


【解决方案1】:

来自默认位置的属性(此处application.properties) 作为类中使用的自定义属性具有更高的优先级。

来自 Spring Boot 文档:

72.3 Change the location of external properties of an application

增加和修改它的一个好方法是添加@PropertySource 应用程序源的注释。传递给的课程 SpringApplication 静态便捷方法,以及使用添加的方法 检查 setSources() 以查看它们是否具有 @PropertySources,并且 如果他们这样做,这些属性会尽早添加到环境中 用于 ApplicationContext 生命周期的所有阶段。 以这种方式添加的属性的优先级低于使用添加的任何属性 默认位置(例如 application.properties),系统 属性、环境变量或命令行。

这个优先级是有意义的,因为您可以在运行时提供的配置(例如application.properties)应该始终能够覆盖应用程序中“硬编码”的配置。


为了测试这个机制,我创建了一个测试项目,

要测试一个类或一个行为,你应该编写一个单元测试。
您可以使用其中一种方法来覆盖 application.properties 值:

  • test.properties 重命名为application.properties 并将其移动到src/test/resources

  • 使用@TestPropertySource。来自 javadoc:

测试属性源的优先级高于从加载的源 操作系统的环境或 Java 系统属性 作为应用程序通过声明方式添加的属性源 @PropertySource 或以编程方式

【讨论】:

  • 感谢您的文档,愚蠢的是我没想到这一点。您对解决方案有什么建议吗?
猜你喜欢
  • 1970-01-01
  • 2021-06-14
  • 2020-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多