Friday, November 30, 2018

Spring depends-on Attribute

This post talks about the depends-on attribute in Spring framework which helps when there is no explicit dependency on a bean.

When there is no explicit dependency

If one bean has a dependency on another, that usually means that one bean is set as a property of another. In Spring framework, typically you accomplish this with the <ref/> element in XML-based configuration metadata.

Quite infrequently you may have a situation where one bean does not explicitly depend on another bean meaning it is not referred in another class as a property or a constructor argument. But one of the bean still depends on another bean and requires another bean to be initialized before its own initialization.

As example, a static initializer in a class needs to be triggered, such as database driver registration.
In that case you can use Spring depends-on attribute. The depends-on attribute can explicitly force one or more beans to be initialized before the bean using this element is initialized.

Spring depends-on attribute example

Suppose there is a class ClassA with it’s own fields, methods and a static block.

There is another class, ClassB with a constructor, but it doesn’t refer to ClassA in anyway. Now you want to make sure that the static block should have executed before the initialization of ClassB bean, which means ClassA should be initialized before ClassB.

 
public class ClassA {
 
 public ClassA(){
  System.out.println("Initializing ClassA");
 }
 // static blank final variable
 static final int i;
 static int b;
 //static block
 static {
  System.out.println("in static block");
  i = 5;
  b = i * 5;
  System.out.println("Values " + i + " " +  b);
 }
 public static int getB() {
  return b;
 }
 public static void setB(int b) {
  ClassA.b = b;
 }
 public static int getI() {
  return i;
 }
}
 
public class ClassB {
 public ClassB(){
  System.out.println("Initializing ClassB");
 }
}

If you define the beans in your XML configuration with out using depends-on attribute there is no guarantee that ClassA will be initialized first.

 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    
    <bean id="classB" class="org.netjs.prog.ClassB">   
    </bean>
    
    <bean id="classA" class="org.netjs.prog.ClassA">
    </bean>
</beans>

You can run it using this test class-

 
import org.netjs.prog.ClassB;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

 public static void main(String[] args) {
  ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
   ("appcontext.xml");
  ClassB cbObj = (ClassB)context.getBean("classB");
  //cbObj.displayValue();
  context.close();
 }

}

Output

 
Initializing ClassB
in static block
Values 5 25
Initializing ClassA

Here you can see ClassB object is initialized first and then ClassA object is initialized and its static block is executed.
But that is not what you want so you can use depends-on attribute to tell the spring framework that ClassA object should be ready before initializing ClassB object.

In that case your XML configuration would change -

 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">
    
    <bean id="classB" class="org.netjs.prog.ClassB" depends-on="classA">  
    </bean>
    
    <bean id="classA" class="org.netjs.prog.ClassA">  
    </bean>
</beans>

Now running it using the test class yields-

 
in static block
Values 5 25
Initializing ClassA
Initializing ClassB

Now you can see that the ClassA is initialized first.

Dependency on multiple beans using depends-on attribute

To express a dependency on multiple beans, supply a list of bean names as the value of the depends-on attribute, with commas, whitespace and semicolons, used as valid delimiters:

<bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao">
      <property name="manager" ref="manager" />
</bean>
<bean id="manager" class="ManagerBean" />
<bean id="accountDao" class="x.y.jdbc.JdbcAccountDao" />

Controlling shutdown order

Dependent beans that define a depends-on relationship with a given bean are destroyed first, prior to the given bean itself being destroyed. If you consider the above example, since ClassB bean is dependent on ClassA bean so ClassB bean will be destroyed first. But note that the destroy time dependency is specified in the case of singleton beans only.

That's all for this topic Spring depends-on Attribute. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. Dependency Injection Using factory-method in Spring
  2. Wiring Collections in Spring
  3. Run Time Injection Using Spring Expression Language(SpEL)
  4. Bean Definition Inheritance in Spring
  5. How to Inject Prototype Scoped Bean in Singleton Bean

You may also like-

  1. Insert\Update using JDBCTemplate in Spring framework
  2. How to read properties file in Spring Framework
  3. Difference between HashMap and ConcurrentHashMap in Java
  4. fail-fast Vs fail-safe iterator in Java
  5. Difference Between CountDownLatch And CyclicBarrier in Java
  6. CopyOnWriteArrayList in Java
  7. Java Multi-threading interview questions
  8. Exception handling and method overriding