Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring bean depends on a conditional bean

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 conditional bean wearing the @ConditionalOnProperty(name = "some.property", havingValue = "true") annotation. So when the property is false then the bean is not instanciated (and that's what we want), and the @DependsOn obviously fails. The goal here is : create the second bean anyway, but create it after the first one if it was created.

Is there a way to do that without removing the @ConditionalOnProperty ? And without playing with the @Order annotation ?

Thank you for your help

like image 334
gnos Avatar asked Mar 23 '18 09:03

gnos


People also ask

What are conditional beans in Spring?

Why do we need Conditional Beans? A Spring application context contains an object graph that makes up all the beans that our application needs at runtime. Spring's @Conditional annotation allows us to define conditions under which a certain bean is included into that object graph.

How do you use a Spring conditional bean?

Conditions based on a Bean definition are present in Spring Application context. Conditions based on a Bean object are present in Spring Application context. Conditions based on some or all Bean properties values. Conditions based on some Resources are present in current Spring Application Context or not.

How do I remove Spring beans based on specific conditions?

In Spring Boot, you can use the @ConditionalOnProperty annotation to enable or disable a particular bean based on the presence of a property. This is very useful if you want to provide optional features to your microservice. And that's it. Your optionalClass bean should resolve to null when you specify mybean.


2 Answers

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:)

like image 126
Mark Bramnik Avatar answered Oct 13 '22 00:10

Mark Bramnik


Instead of using @DependsOn 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();
  }
}
like image 30
Jonas Pedersen Avatar answered Oct 13 '22 00:10

Jonas Pedersen