我想根据 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
来解决) > 另一方面,这会增加代码冗余)
- 示例:像 加载 default.properties <-然后加载并覆盖 -> customer.properties 这样的行为将不再起作用(尽管这应该可以使用
关于java - Spring:从文件中读取属性为什么执行 Condition::match,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38121421/