Spring @PostConstruct & @PreDestroy Annotation

In this chapter you will learn how to implement the @PostConstruct and @PreDestroy which work similar to init-method and destroy-method in bean configuration file (spring.xml) describe in earlier chapter or implement the InitializingBean and DisposableBean in your bean class.
To    use    @PostConstruct   and    @PreDestroy    you   have    to    register   the CommonAnnotationBeanPostProcessor   at   bean   configuration   or    specifying   the <context:annotation-config /> in the bean configuration file (spring.xml).

To define setup and teardown for a bean, we simply declare the with init-method and/or destroy-method parameters. The init-method attribute specifies a method that is to be called on the bean immediately upon instantiation. Similarly, destroy-method specifies a method that is called just before a bean is removed from the container.

Note:
The @PostConstruct and @PreDestroy annotation are not belong to Spring, it’s located in the J2ee library – common-annotations.jar

You can use @PostConstruct annotation as an alternate of initialization callback and @PreDestroy annotation as an alternate of destruction callback as explained in the below example.
Circle.java
package com.dineshonjava.sdnext.jsr.tutorial;

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

public class Circle
{ 
 private Point center;
 
 @Resource(name="pointB")
 public void setCenter(Point center) 
 {
     this.center = center;
 }
 
 public void draw() 
 {
System.out.println("Circle is drawn of center ("+center.getX()+", "+center.getY()+")");
 }
 
 @PostConstruct
 public void initializeCircle()
 {
     //populates the circle data cache upon initialization...  
     System.out.println("Init of Circle");
 }
 
 @PreDestroy
 public void destroyCircle()
 {
    //clears the circle related cache upon destruction..  
    System.out.println("Destroy of Circle");
 }
}
Point.java
package com.dineshonjava.sdnext.jsr.tutorial;

public class Point
{
 private int x;
 private int y;
 /**
  * @return the x
  */
 public int getX() {
  return x;
 }
 /**
  * @param x the x to set
  */
 public void setX(int x) {
  this.x = x;
 }
 /**
  * @return the y
  */
 public int getY() {
  return y;
 }
 /**
  * @param y the y to set
  */
 public void setY(int y) {
  this.y = y;
 }
}
DrawingApp.java
package com.dineshonjava.sdnext.jsr.tutorial;

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

/**
 * @author Dinesh
 *
 */
public class DrawingApp 
{
 /**
  * @param args
  */
 public static void main(String[] args) 
 {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
context.registerShutdownHook();
Circle circle = (Circle) context.getBean("circle");
circle.draw();
 }
}

By default, Spring will not aware of the @PostConstruct and @PreDestroy annotation. To enable it, you have to either register "CommonAnnotationBeanPostProcessor" or specify the <context:annotation-config /> in bean configuration file(spring.xml),

1. Using CommonAnnotationBeanPostProcessor
spring.xml
<beans xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:security="http://www.springframework.org/schema/security" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="http://www.springframework.org/schema/beans">
 
<bean class="com.dineshonjava.sdnext.jsr.tutorial.Circle" id="circle"></bean>
  
<bean class="com.dineshonjava.sdnext.jsr.tutorial.Point" id="pointA">
  <property name="x" value="0"></property>
  <property name="y" value="0"></property>
</bean>

<bean class="com.dineshonjava.sdnext.jsr.tutorial.Point" id="pointB">
  <property name="x" value="-20"></property>
  <property name="y" value="0"></property>
</bean>
  
<bean class="com.dineshonjava.sdnext.jsr.tutorial.Point" id="pointC">
  <property name="x" value="20"></property>
  <property name="y" value="0"></property>
</bean> 

<bean class="com.dineshonjava.sdnext.jsr.tutorial.Point" id="center">
  <property name="x" value="10"></property>
  <property name="y" value="10"></property>
</bean>
  
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"></bean>
</beans>

2. Using <context:annotation-config />
spring.xml
<beans xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:security="http://www.springframework.org/schema/security" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:schemalocation="http://www.springframework.org/schema/beans">
 
<bean class="com.dineshonjava.sdnext.jsr.tutorial.Circle" id="circle"></bean>
  
<bean class="com.dineshonjava.sdnext.jsr.tutorial.Point" id="pointA">
  <property name="x" value="0"></property>
  <property name="y" value="0"></property>
</bean>

<bean class="com.dineshonjava.sdnext.jsr.tutorial.Point" id="pointB">
  <property name="x" value="-20"></property>
  <property name="y" value="0"></property>
</bean>
  
<bean class="com.dineshonjava.sdnext.jsr.tutorial.Point" id="pointC">
  <property name="x" value="20"></property>
  <property name="y" value="0"></property>
</bean> 

<bean class="com.dineshonjava.sdnext.jsr.tutorial.Point" id="center">
  <property name="x" value="10"></property>
  <property name="y" value="10"></property>
</bean>
  
<context:annotation-config></context:annotation-config>
</beans>

Once you are done with creating source and bean configuration files, let us run the application. If everything is fine with your application, this will print the following message:

Output:
Jul 14, 2012 1:57:00 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@145d068: startup date [Sat Jul 14 01:57:00 IST 2012]; root of context hierarchy
Jul 14, 2012 1:57:00 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring.xml]
Jul 14, 2012 1:57:00 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@4e79f1: defining beans [circle,pointA,pointB,pointC,center,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0]; root of factory hierarchy
Init of Circle
Circle is drawn of center (-20, 0)
Destroy of Circle






No comments:

Post a Comment