java - Spring:从文件中读取属性为什么执行 Condition::match

标签 java spring

我想根据 application.properties 中的标志实现一个条件 Bean。示例:

// application.properties
service=foobar

这个想法是使不同的服务实现可配置,假设我在 Spring 中获得了该服务的中央配置类:

@Configuration
@Import({ServiceA.class, ServiceB.class, ...})
public class ServiceConfiguration {
    ...
}

可能的服务实现如下所示

@Configuration
public class ServiceA implements Condition {

    @Bean
    @Conditional(ServiceA.class)
    public Service service() {
        Service a = ...
        return a; 
    }

    @Override
    public boolean matches(
            ConditionContext conditionContext, 
            AnnotatedTypeMetadata annotatedTypeMetadata) {
        // getProperty will alsways return null for some reason
        return conditionContext
                .getEnvironment()
                 .getProperty("service")
                  .equals("ServiceA");
    }

    // This will be null anyways
    @Value("${service}")
    private String confService;
}

由于实现 Condition 的类(这里只是同一个类 ServiceA)将通过默认构造函数 @Value 进行初始化 - 注入(inject)不会工作。然而,据我了解 getProperty() 应该返回正确的值。我究竟做错了什么?此时我如何访问应用程序属性?

最佳答案

我在“dirty workarround”中发现,我真的不喜欢这个解决方案,但是,它解决了问题。如前所述here @PropertySource 修复了问题(在此处发布之前我没有尝试过此操作,因为它不是公认的答案)。

@Configuration
@PropertySource(value="file:config/application.properties")
public class ServiceA implements Condition {

    @Bean
    @Conditional(ServiceA.class)
    public Service service() {
        Service a = ...
        return a; 
    }

    @Override
    public boolean matches(
            ConditionContext conditionContext, 
            AnnotatedTypeMetadata annotatedTypeMetadata) {
        // Will work now
        return conditionContext
                .getEnvironment()
                 .getProperty("service")
                  .equals("ServiceA");
    }    

}

虽然这有效,但我不喜欢它有几个原因:

  • 对于每个实现,我都有代码冗余(提供配置文件的路径)
  • 当有多个配置文件时,它非常难以维护
    • 示例:像 加载 default.properties <-然后加载并覆盖 -> customer.properties 这样的行为将不再起作用(尽管这应该可以使用 @PropertySources 来解决) > 另一方面,这会增加代码冗余)

关于java - Spring:从文件中读取属性为什么执行 Condition::match,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38121421/

相关文章:

Java运行时编译

java - 在 Eclipse 树列的项目中选择

java - 从 Appengine 中的 blob 键获取文件名

java - "java.lang.IllegalArgumentException: Not a managed type ..."当实体类和Spring数据存储库在同一个包中时

java - 扩展 PropertyPlaceholderConfigurer 时,我无法对扩展类使用注释

java - 所有测试都在 Intellij 中使用 Spring Boot 和 JUnit5 终止

spring - 在代码上定义 DataSource bean

java - 错误 : Could not find or load main class in SpringBoot Application

java - 字符串是不可变的。到底是什么意思?

java - 保存多线程游戏