按属性切换spring boot bean定义并允许自定义bean

时间:2017-03-31 08:25:22

标签: java spring-boot

假设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并仍然允许用户覆盖?

1 个答案:

答案 0 :(得分:1)

@ConditionalOnPropertyOnPropertyCondition实施,查看Environment以检查属性是否存在。在@ConfigurationProperties带注释的类中添加属性不会将该值添加到属性中。因此检查仍然失败。

但是,@ConditionalOnProperty als具有matchIfMissing属性,您可以设置该属性。默认值为false,因此,如果您将true设置为foo,则如果未明确设置该值,则该值将匹配。

@ConditionalOnProperty(name="service-type", 
                       havingValue = "foo", 
                       matchIfMissing=true)