Spring bean depends on a conditional bean

后端 未结 4 754
小鲜肉
小鲜肉 2021-02-19 02:58

I want a spring bean to be instanciated after another bean. So I simply use the @DependsOn annotation.

The thing is : this other bean is a

相关标签:
4条回答
  • 2021-02-19 03:12

    How about the following approach:

    interface Something {}
    
    public class FirstBean implements Something {}
    
    public class SecondBean implements Something{} // maybe empty implementation
    

    Now the configuration goes like this:

    @Configuration
    public class MyConfiguration {
    
      @Bean(name = "hello")
      @ConditionalOnProperty(name = "some.property", havingValue = true) 
      public Something helloBean() {
         return new FirstBean();
      }
    
      @Bean(name = "hello")
      @ConditionalOnProperty(name = "some.property", havingValue = false) 
      public Something secondBean() {
         return new SecondBean();
      }
    
      @Bean
      @DependsOn("hello")
      public MyDependantBean dependantBean() {
           return new MyDependantBean();
      }
    }
    

    The idea is to create the "Something" bean anyway (even if its an empty implementation), so that the dependant bean will depend on Something in any case.

    I've not tried this myself, you know, spring is full of magic, but probably it worth a try:)

    0 讨论(0)
  • 2021-02-19 03:14

    Instead of using @DependsO you can use @AutoConfigureAfter()which will allow the second bean to be created even if the first bean was not created, but still keep the order.

    @Configuration
    public class FirstConfiguration {
    
      @Bean(name = "firstBean")
      @ConditionalOnProperty(name = "some.property", havingValue = true) 
      public FirstBean firstBean() {
         return new FirstBean();
      }
    }
    
    @Configuration
    @AutoConfigureAfter(name = {"firstBean"})
    public class SecondConfiguration {
    
      @Bean
      public SecondBean secondBean() {
           return new SecondBean();
      }
    }
    
    0 讨论(0)
  • 2021-02-19 03:15

    You can use custom condition class:

    public class BeanPresennceCondition implements Condition {
    
      @Override
      public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
          FirstBean firstBean = null;
          try {
          firstBean = (FirstBean)context.getBeanFactory().getBean("firstBean"); 
          }catch(NoSuchBeanDefinitionException ex) {
    
          }
         return firstBean != null;
      }
    }
    
    0 讨论(0)
  • 2021-02-19 03:23

    Could you create two definitions for the dependent bean, to cater for the two cases where the other bean is or isn't there?

    E.g.:

    @Bean(name = "myDependentBean")
    @DependsOn("otherBean")
    @ConditionalOnProperty(name = "some.property", havingValue = true) 
    public DependentBean myDependentBean() {
        return new DependentBean();
    }
    
    @Bean(name = "myDependentBean")
    @ConditionalOnProperty(name = "some.property", havingValue = false, matchIfMissing = true) 
    public DependentBean myDependentBean_fallback() {
        return new DependentBean();
    }
    

    (This is the approach I've just taken today to solve a similar problem!)

    Then Spring would use the first definition if some.property is true, and so instantiate myDependentBean after otherBean. If some.property is missing or false, Spring will use the second definition, and so not care about otherBean.

    Alternatively, you could probably use @ConditionalOnBean/@ConditionalOnMissingBean on these, instead of @ConditionalOnProperty (though I've not tried this).

    0 讨论(0)
提交回复
热议问题