Spring Boot使用@ConfigurationProperties
注释为我们提供了类型化的配置对象。其中一个优点是在使用Spring Boot注释处理器时可以在IDE中免费获取属性名称。另一个是:验证。
现在,我想根据属性的值来设置bean。实际上,我有两个接口的实现,这个属性告诉我应该使用哪一个。我可以像这样实现它:
ImplementationA.java
@Component
@ConditionalOnProperty(name = "foo.bar", havingValue = "a")
public class ImplementationA implements SomeInterface { ... }
ImplementationB.java
@Component
@ConditionalOnProperty(name = "foo.bar", havingValue = "b")
public class ImplementationB implements SomeInterface { ... }
application.yml
foo:
bar: "a"
但是,我失去了键入配置的优势。所以我想在@ConfigurationProperties
对象中声明这个属性:
FooProperties.java
@ConfigurationProperties(prefix = "foo")
public class FooProperties {
private String bar;
public String getBar() { ... }
public void setBar(String bar) { ... }
}
这仍然可以,但是当我在此类中声明bar
的默认值时,@ConditionalOnProperty
显然不会被Environment
选中,因为此注释直接针对@ConfigurationProperties
(按设计)。所以也许最好不要混合这些概念。
是否有办法根据@Conditional
对象中的值设置条件bean?最好使用一些@Configuration
注释而不创建keyStore.isKeyEntry(alias)
bean,因为这意味着样板代码。
答案 0 :(得分:1)
它可能并不那么性感,但是潜在的解决方案是将您的配置自动连接到SomeInterfaceConfiguration中,该接口创建基于FooProperties的服务实现。
即
@Configuration
public class SomeInterfaceConfiguration {
@Bean
@Autowired
public SomeInterface someInterface(FooProperties fooProperties){
if("a".equals(fooProperties.getBar()){
return SomeInterfaceImplementationA();
} else {
return SomeInterfaceImplementationB();
}
}
}
另一种选择是使用配置文件,但这与所需的解决方案不同。 即具有默认实现。
@Component
public class ImplementationA
@Profile("b")
@Primary
@Component
public class ImplementationB