假设interface Service {}
。我的平台提供了这个接口的两个实现:
FooService
BarService
我现在想要的是用户可以通过yaml选择要使用的服务。另外,如果他宁愿使用CustomService
,他应该能够忽略两个默认实现并提供自己的bean。
注意:这是一个初学者项目,因此用户向我的jar添加一个依赖项,并且应该注入FooService,BarService或CustomService,具体取决于他的yaml / configiguration。
这是我试过的:
@ConfigurationProperties
我有一个字段String serviceType = "foo"
(foo是默认值)在我的自动配置中,我提供了两个bean:
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfiguration {
@Bean
@ConditionalOnMissingBean(Service.class) // only active if no custom present
@ConditionalOnProperty(name="service-type", havingValue = "foo")
public Service fooService() {
return new FooService();
}
@Bean
@ConditionalOnMissingBean(Service) // only active if no custom present
@ConditionalOnProperty(name="service-type", havingValue = "bar")
public Service barService() {
return new BarService();
}
}
创建第一个简单测试,我假设注入了FooService,但我得到了一个ApplicationContext异常,因为没有为Service
接口注册bean。在这个测试中,我不在yaml中为“service-type”设置任何值,我依赖于默认的“foo”。
我的错误在哪里?我不能在两个bean上有ConditionalOnMissingBean吗?在评估财产条件时是否考虑默认的“foo”?是否有其他方法可以解决一般问题:提供多个默认bean并仍然允许用户覆盖?
答案 0 :(得分:1)
@ConditionalOnProperty
由OnPropertyCondition
实施,查看Environment
以检查属性是否存在。在@ConfigurationProperties
带注释的类中添加属性不会将该值添加到属性中。因此检查仍然失败。
但是,@ConditionalOnProperty
als具有matchIfMissing
属性,您可以设置该属性。默认值为false
,因此,如果您将true
设置为foo
,则如果未明确设置该值,则该值将匹配。
@ConditionalOnProperty(name="service-type",
havingValue = "foo",
matchIfMissing=true)