Recent Posts

Saturday, 8 June 2019

Bean Life Cycle

Bean Life cycle
     In spring framework applications, when IOC Container recognizes all the beans definitions in beans configuration file then IOC Container will execute that bean by using the following lifecycle actions.
1. Bean Class Loading
2. Bean Instantiation
3. Bean Initialization
4. Bean Destruction

1. Bean Class Loading
     When IOC Container recognized fully qualified names of the bean classes in beans configuration file then IOC Container will load the specified bean class byte code to the memory. To load bean class bytecode to the memory, IOC Container will use the following method.
public static Class forName(String class_Name)throws ClassNotFoundException
E.g.
Class c = Class.forName(“com.ashok.spring.core.bean.scopes.prototype.beans.Employee");

2. Bean Instantiation
     In Spring applications, after loading bean class bytecode to the memory, IOC Container will create object for the bean class. In Spring applications, we are able to use the following three approaches to create Bean objects.
1. By using Constructor directly.
2. By Using Static Factory Method
3. By Using Instance Factory Method

1. Bean Instantiation through Constructors
     If we want to create bean objects by using constructors then we must provide 0-arg constructor in bean class irrespective of bean class constructor scopes.
Note: In Bean class, if we provide parameterized constructor then IOC Container will rise an exception.
E.g.
Bean Class
package com.ashok.spring.core.bean.instantiation.constructor.beans;

/**
 * 
 * @author Ashok Kumar
 *
 */
public class Employee {
   public Employee() {
      System.out.println("Bean Instantiation using constructor");
   }

   public String getStatus() {
      return "Hey..!! Bean created using constructor..!!";
   }
}
Config File
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="emp"
        class="com.ashok.spring.core.bean.instantiation.constructor.beans.Employee">
    </bean>
</beans>
Client Application
package com.ashok.spring.core.bean.instantiation.constructor.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ashok.spring.core.bean.instantiation.constructor.beans.Employee;

/**
 * 
 * @author Ashok Kumar
 *
 */
public class TestSpringApplication {
   @SuppressWarnings("resource")
   public static void main(String[] args) {
      String configFile = "/com/ashok/spring/core/bean/instantiation/constructor/config/applicationContext.xml";
      ApplicationContext context = new ClassPathXmlApplicationContext(configFile);
      Employee emp = (Employee) context.getBean("emp");
      System.out.println(emp.getStatus());
   }
}
Output
Output
Bean Instantiation using constructor
Hey...!! Bean created using constructor...!!
2. Bean Instantiation through Static Factory Method
     In this approach, first we have to define static factory method in Bean class and we have to configure that static factory method in bean definition in beans configuration file.
E.g.
Bean Class
package com.ashok.spring.core.bean.instantiation.staticfactory.beans;

/**
 * 
 * @author Ashok Kumar
 *
 */
public class Employee {
   public static Employee getInstance() {
      System.out.println("Bean Instantiation using static factory..!!");
      return new Employee();
   }

   public String getStatus() {
      return "Hey..!! Bean created using static factory..!!";
   }
}
Config File 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="emp"
        class="com.ashok.spring.core.bean.instantiation.staticfactory.beans.Employee"
        factory-method="getInstance">
    </bean>
</beans>
Client Application
package com.ashok.spring.core.bean.instantiation.staticfactory.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ashok.spring.core.bean.instantiation.staticfactory.beans.Employee;

/**
 * 
 * @author Ashok Kumar
 *
 */
public class TestSpringApplication {
   @SuppressWarnings("resource")
   public static void main(String[] args) {
      String configFile = "/com/ashok/spring/core/bean/instantiation/staticfactory/config/applicationContext.xml";
      ApplicationContext context = new ClassPathXmlApplicationContext(configFile);
      Employee emp = (Employee) context.getBean("emp");
      System.out.println(emp.getStatus());
   }
}
Output
Bean Instantiation using static factory...!!
Hey...!! Bean created using static factory...!!
3. Bean Instantiation through Instance Factory Method
     In this approach, we have to define a separate factory class with instance factory method and we have to configure factory class as bean in beans configuration file then we have to configure factory class and factory method in the original bean class definition by using "factory-bean" and "factory-method" attributes.
E.g
Bean Class
package com.ashok.spring.core.bean.instantiation.instancefactory.beans;

/**
 * 
 * @author Ashok Kumar
 *
 */
public class Employee {
   public String getStatus() {
      return "Hey..!! Bean created using instance factory..!!";
   }
}
Factory Class
package com.ashok.spring.core.bean.instantiation.instancefactory.factory;

import com.ashok.spring.core.bean.instantiation.instancefactory.beans.Employee;
/**
 * 
 * @author ashok.mariyala
 *
 */
public class EmployeeFactory {
   public Employee getInstance() {
      System.out.println("Bean Instantiation using instance factory..!!");
      return new Employee();
   }
}
Config File
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="emp"
      class="com.ashok.spring.core.bean.instantiation.instancefactory.beans.Employee"
      factory-method="getInstance" factory-bean="factory">
    </bean>
    <bean id="factory" class="com.ashok.spring.core.bean.instantiation.instancefactory.factory.EmployeeFactory" />
</beans>
Client Application
package com.ashok.spring.core.bean.instantiation.instancefactory.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ashok.spring.core.bean.instantiation.instancefactory.beans.Employee;

/**
 * 
 * @author Ashok Kumar
 *
 */
public class TestSpringApplication {
   @SuppressWarnings("resource")
   public static void main(String[] args) {
      String configFile = "/com/ashok/spring/core/bean/instantiation/instancefactory/config/applicationContext.xml";
      ApplicationContext context = new ClassPathXmlApplicationContext(configFile);
      Employee emp = (Employee) context.getBean("emp");
      System.out.println(emp.getStatus());
   }
}
Output
Bean Instantiation using instance factory...!!
Hey...!! Bean created using instance factory...!!
3. Bean Initialization and Bean Destruction
     As part of Beans lifecycle, IOC Container has to perform Beans initialization after the Bean Instantiation and IOC Container has to perform Bean destruction after executing the business logic or at the time of shutdown the IOC Container. There are three ways to perform Beans initialization and destruction in Spring Framework.
1. By using Custom initialization and destruction methods.
2. By using InitializingBean and DesposableBean callback interfaces.
3. By using @PostConstruct and @Predestroy annotations

1. By using Custom initialization and destruction methods
     In this approach, we have to define user defined initialization and destruction methods with any name and we have to configure that user defined methods in beans definitions in beans configuration file by using "init-method" and "destroy-method" attributes in <bean> tag.
E.g
package com.ashok.spring.core.bean.initialization.custom.beans;

/**
 * 
 * @author Ashok Kumar
 *
 */
public class Employee {
   public void init() {
      System.out.println("User defined init() method");
   }
   
   public void destroy() {
      System.out.println("User defined destroy() method");
   }
   
   public void getMessage() {
      System.out.println("Inside Employee class..!!");
   }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="emp"
        class="com.ashok.spring.core.bean.initialization.custom.beans.Employee"
        init-method="init" destroy-method="destroy" />
</beans>
package com.ashok.spring.core.bean.initialization.custom.test;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ashok.spring.core.bean.initialization.custom.beans.Employee;

/**
 * 
 * @author Ashok Kumar
 *
 */
public class TestSpringApplication {
   public static void main(String[] args) {
      String configFile = "/com/ashok/spring/core/bean/initialization/custom/config/applicationContext.xml";
      AbstractApplicationContext context = new ClassPathXmlApplicationContext(configFile);
      Employee emp = (Employee) context.getBean("emp");
      System.out.println(emp);
      context.close();
   }
}
Output
User defined init() method
com.ashok.spring.core.bean.initialization.custom.beans.Employee@3e9b1010
User defined destroy() method
2. By using InitializingBean and DesposableBean callback interfaces
     In Spring framework, InitializingBean is a callback interface, it provides the following method to execute while performing bean initialization by IOC Container.
public void afterPropertiesSet()throws Exception
Note: This method will be executed by the container after executing all the setXXX() methods of bean class by ApplicationContext.
     In Spring framework, DisposableBean is a callback interface, it provides the following method to execute while performing Bean Destruction by IOC Container.
public void destroy()
E.g.
package com.ashok.spring.core.bean.initialization.callbackinterface.beans;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

/**
 * 
 * @author Ashok Kumar
 *
 */
public class Employee implements InitializingBean, DisposableBean {
   @Override
   public void destroy() {
      System.out.println("Inside destroy() method");
   }
   
   public void getMessage() {
      System.out.println("Inside Employee class..!!");
   }

   @Override
   public void afterPropertiesSet() throws Exception {
      System.out.println("Inside afterPropertiesSet() method");
   }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="emp"
        class="com.ashok.spring.core.bean.initialization.callbackinterface.beans.Employee" />
</beans>
package com.ashok.spring.core.bean.initialization.callbackinterface.test;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ashok.spring.core.bean.initialization.callbackinterface.beans.Employee;

/**
 * 
 * @author Ashok Kumar
 *
 */
public class TestSpringApplication {
   public static void main(String[] args) {
      String configFile = "/com/ashok/spring/core/bean/initialization/callbackinterface/config/applicationContext.xml";
      AbstractApplicationContext context = new ClassPathXmlApplicationContext(configFile);
      Employee emp = (Employee) context.getBean("emp");
      System.out.println(emp);
      context.close();
   }
}
Output
Inside afterPropertiesSet() method
com.ashok.spring.core.bean.initialization.callbackinterface.beans.Employee@3e9b1010
Inside destroy() method
3. By using @PostConstruct and @Predestroy annotations
☀ @PostConstruct annotation will make a method to execute by the IOC Container while performing Beans iniitalization.
☀ @Predestroy annotation will make a method to execute by the IOC Container while performing Bean Destruction.
package com.ashok.spring.core.bean.initialization.annotations.beans;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * 
 * @author Ashok Kumar
 *
 */
public class Employee {
   @PreDestroy
   public void destroy() {
      System.out.println("Inside @@PreDestroy annotation method");
   }
   
   public void getMessage() {
      System.out.println("Inside Employee class..!!");
   }

   @PostConstruct
   public void init() throws Exception {
      System.out.println("Inside @PostConstruct annotation method");
   }
}
<?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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:annotation-config />
    <bean id="emp"
        class="com.ashok.spring.core.bean.initialization.annotations.beans.Employee" />
</beans>
package com.ashok.spring.core.bean.initialization.annotations.test;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ashok.spring.core.bean.initialization.annotations.beans.Employee;

/**
 * 
 * @author Ashok Kumar
 *
 */
public class TestSpringApplication {
   public static void main(String[] args) {
      String configFile = "/com/ashok/spring/core/bean/initialization/annotations/config/applicationContext.xml";
      AbstractApplicationContext context = new ClassPathXmlApplicationContext(configFile);
      Employee emp = (Employee) context.getBean("emp");
      System.out.println(emp);
      context.close();
   }
}
Output
Output
Inside @PostConstruct annotation method
com.ashok.spring.core.bean.initialization.annotations.beans.Employee@57f23557
Inside @@PreDestroy annotation method
Note: In general, in spring framework applications, we are able to use either of the above three approaches to perform beans initialization and destruction, we are not using all three approaches at a time. If we use all the above three approaches in single bean then IOC Container will execute the above three approaches provided initialization methods and destruction methods in the following order.
Initialization order1. an initialization method marked with @Postconstruct annotation.
2. afterPropertiesSet() method provided by InnitializingBean callback interface.
3. an initialization method configured with "init-method" in <bean> tag in beans configuration file

Destruction Order
1. A Destruction method marked with @Predestroy annotation
2. destroy() method provided by DisposableBean callback interface.
3. A destruction method configured with "destroy-method" annotation in <bean> tag in beans configuration file.
Note: If we have same initialization method and destruction method in more than one bean class in spring application then we are able to provide common init method and destroy method configuration by using "default-init-method" attribute and "default-destroy-method" attribute in <beans> tag [not in <bean> tag] without providing "init-method" and "destroy-method" attributes in <bean> tag at each and every bean configuration.

Next Tutorial : Bean Inheritance

Previous Tutorial : Bean Definition
 

1 comment: