February 15, 2022

Spring @DependsOn Annotation

Sometimes dependencies between beans may not be direct but you may still want to ensure that a specific bean is initialized before another bean. For example in one bean there is a static block which has to be executed before another bean is initialized. You can use Spring @DependsOn annotation to explicitly force one or more beans to be initialized.

You will annotate one of the bean using @DependsOn annotation and the beans that are specified with @DependsOn are guaranteed to be created by the container before this bean.

For example in the following definition it is guaranteed that the beanA and beanB are created by the Spring IOC container before creating beanC.

@Bean
@DependsOn({"beanA","beanB"})
public ClassC beanC() {
  ..
  ..
}

Spring @DependsOn annotation example

Here is the complete example where three classes ClassA, ClassB and ClassC are defined. You want to ensure than ClassA and ClassB are initialized before ClassC is initialized.

public class ClassA {
  public ClassA(){
    System.out.println("In constructor of ClassA");
  }
  //static block
  static {
    System.out.println("in static block ClassA");
    System.out.println("Register DB Driver as a one time activity");
  }
}
public class ClassB {
  public ClassB(){
    System.out.println("In constructor of ClassB");
  }
}
public class ClassC {
  public ClassC(){
    System.out.println("In constructor of ClassC");
  }
}
Java configuration class
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import com.knpcode.springbeans.ClassA;
import com.knpcode.springbeans.ClassB;
import com.knpcode.springbeans.ClassC;
 
@Configuration
public class AppConfig {
  @Bean
  @DependsOn({"beanA","beanB"})
  public ClassC beanC() {
    return new ClassC();
  }
  @Bean
  public ClassB beanB() {
    return new ClassB();
  }
  @Bean
  public ClassA beanA() {
    return new ClassA();
  }
}

As you can see here @DependsOn is used with a method annotated with Bean (beanC()) and specifies the other two beans @DependsOn({"beanA","beanB"}). This enforces that beanA and beanB are initialized before beanC.

For running the application you can use the following class.

public class App {
  public static void main(String[] args) {
    AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    ClassC obj = context.getBean("beanC", ClassC.class);
    context.close();
  }
}
Output
10:52:01.160 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'beanA'
in static block ClassA
Register DB Driver as a one time activity
In constructor of ClassA
10:52:01.293 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'beanB'
In constructor of ClassB
10:52:01.297 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'beanC'
In constructor of ClassC

As you can see from the output beanA and beanB are initialized first.

That's all for the topic Spring @DependsOn Annotation. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment