Java Spring:从文件读取属性为什么执行条件::匹配

Java Spring:从文件读取属性为什么执行条件::匹配,java,spring,Java,Spring,我想根据application.properties中的标志实现一个条件Bean。例如: // application.properties service=foobar 我们的想法是使不同的服务实现可配置,假设我在Spring中为此服务获得了一个中央配置类: @Configuration @Import({ServiceA.class, ServiceB.class, ...}) public class ServiceConfiguration { ... } 可能的服务实现如下

我想根据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;
}
由于实现
条件
(此处仅为同一类
ServiceA
)的类将通过默认构造函数
@Value
初始化,因此注入将不起作用。然而,据我所知,
getProperty()
应该返回正确的值。我做错了什么?此时如何访问应用程序属性?

我在“脏工作区”找到了,我真的不喜欢这种解决方案,但它解决了问题。如前所述,
@PropertySource
解决了这个问题(我在这里发布之前没有尝试过,因为它不是一个认可的答案)

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

  • 对于每个实现,我都有代码冗余(提供一个配置文件的路径)
  • 当有多个配置文件时,它是高度不可维护的
    • 示例:像load default.properties customer.properties这样的行为将不再起作用(尽管这应该可以通过使用
      @PropertySources
      来解决,另一方面,这将增加代码冗余)
@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");
    }    

}