This tutorial will show you how we can use @PostConstruct and @PreDestroy in Spring. @PostConstruct and @PreDestroy annotations are generally considered best practice for receiving lifecycle callbacks in a modern Spring application. Using these annotations means that our beans are not coupled to Spring specific interfaces. For more information please refer to http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html#beans-postconstruct-and-predestroy-annotations

Sometimes we need to load some data or perform initialization work after all necessary properties on the bean have been set by the container. In this example we will load data from database during application startup and set that value to a System property so that the value will be set only once and that value can be used later after retrieving from the System property.
For this tutorial we will create a standalone maven project in Eclipse. If you already have an idea on how to create a maven project in Eclipse will be great otherwise I will tell you here how to create a maven project in Eclipse.

Prerequisites

The following configurations are required in order to run the application

Eclipse Kepler
JDK 1.7
Have maven installed and configured
Spring dependencies in pom.xml

Now we will see the below steps how to create a maven based spring project in Eclipse

Step 1. Create a standalone maven project in Eclipse

Go to File -> New -> Other. On popup window under Maven select Maven Project. Then click on Next. Select the workspace location – either default or browse the location. Click on Next. Now in next window select the row as highlighted from the below list of archtypes and click on Next button.

maven-arctype-quickstart

Now enter the required fields (Group Id, Artifact Id) as shown below

Group Id : com.roytuts
Artifact Id : spring-postconstruct-predestroy

Step 2. Modify the pom.xml file as shown below.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.roytuts</groupId>
    <artifactId>spring-postconstruct-predestroy</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
 
    <name>spring-postconstruct-predestroy</name>
    <url>http://maven.apache.org</url>
 
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <jdk.version>1.8</jdk.version>
        <junit.version>4.11</junit.version>
        <mysql.version>5.1.27</mysql.version>
        <org.springframework.version>4.1.5.RELEASE</org.springframework.version>
    </properties>
 
    <dependencies>
        <!-- Spring framework -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
 
        <!-- mysql driver -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
 
        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${jdk.version}</source>
                    <target>${jdk.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Step 3. If you see JRE System Library[J2SE-1.4] then change the version by below process

Do right-click on the project and go to Build -> Configure build path, under Libraries tab click on JRE System Library[J2SE-1.4], click on Edit button and select the appropriate jdk 1.8 from the next window. Click on Finish then Ok.

Step 4. Create src/main/resources folder for putting the resource files.

Do right-click on the project and go New -> Source Folder. Give Folder name: as src/main/resources and click on Finish button.

Step 5. Create an XML file under src/main/resources.

Do right-click on src/main/resources in the project and go New -> file. Give File name: as spring-postconstruct-predestroy-properties.xml and click on Finish button.

<?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:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd">
 
    <bean id="jdbcProperties"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
        name="configProperties">
        <property name="order" value="99999" />
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
        <property name="ignoreUnresolvablePlaceholders" value="true" />
        <property name="properties">
            <value>
                
                JDBC.DRIVER=com.mysql.jdbc.Driver
                JDBC.URL=jdbc:mysql://localhost:3306/roytuts
                JDBC.USERNAME=root
                JDBC.PASSWORD=root
 
            </value>
        </property>
    </bean>
 
</beans>

Step 6. Create spring-postconstruct-predestroy-datasource.xml file under src/main/resources with the below content.

<?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:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:task="http://www.springframework.org/schema/task"
    xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd">
 
    <context:annotation-config></context:annotation-config>
    <import resource="spring-postconstruct-predestroy-properties.xml" />
 
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${JDBC.DRIVER}" />
        <property name="url" value="${JDBC.URL}" />
        <property name="username" value="${JDBC.USERNAME}" />
        <property name="password" value="${JDBC.PASSWORD}" />
    </bean>
 
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource" />
    </bean>
    
    <bean id="flagDAO" class="com.roytuts.spring.dao.impl.FlagDAOImpl" />
 
</beans>

Step 7. Create a MySQL table

CREATE TABLE `flag` (
  `flag_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `flag_val` varchar(30) NOT NULL,
  PRIMARY KEY (`flag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Step 8. Create a POJO class for flag.

package com.roytuts.spring.dto;
 
public class Flag {
 
    private Integer flagId;
    private String flagVal;
 
    public Flag() {
    }
 
    public Flag(Integer flagId, String flagVal) {
        this.flagId = flagId;
        this.flagVal = flagVal;
    }
 
    public Integer getFlagId() {
        return flagId;
    }
 
    public void setFlagId(Integer flagId) {
        this.flagId = flagId;
    }
 
    public String getFlagVal() {
        return flagVal;
    }
 
    public void setFlagVal(String flagVal) {
        this.flagVal = flagVal;
    }
 
}

Step 9. Create a DAO in com.roytuts.spring.dao package

package com.roytuts.spring.dao;
 
import java.util.List;
 
import com.roytuts.spring.dto.Flag;
 
public interface FlagDAO {
 
    void selectFlag();
 
}

Note : if you get error then you can change the Compiler compliance level, Generated .class files compatibility, Source compatibility to 1.7

Step 10. Now create a DAO implementation class in com.roytuts.spring.dao.impl package.

package com.roytuts.spring.dao.impl;
 
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
 
import com.roytuts.spring.dao.FlagDAO;
import com.roytuts.spring.dto.Flag;
 
public class FlagDAOImpl implements FlagDAO {
 
    @Autowired
    private JdbcTemplate jdbcTemplate;

    private final String SQL_SELECT_FLAG_VAL = "select flag_val from flag where flag_id = 1";
    
    @Override
    @PostConstruct // do some initialization work
    public void selectFlag() {
        String val = jdbcTemplate.queryForObject(SQL_SELECT_FLAG_VAL, null, String.class);
        setDbFlag(val);
    }
    
    @PreDestroy // do some destruction work (like releasing pooled connections)
    public void cleanFlag() {
        System.setProperty("dbFlag", null);
    }
    
    private void setDbFlag(String dbFlag) {
        System.setProperty("dbFlag", dbFlag);
        System.out.println("DB Flag : " + System.getProperty("dbFlag"));
    }
 
}

Step 11. Create JUnit test case under src/test/java folder.

package com.roytuts.spring.dao.impl;
 
import java.util.ArrayList;
import java.util.List;
 
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.roytuts.spring.dto.Flag;
 
public class FlagDAOImplTest {
 
    private FlagDAO flagDAO;
 
    @Before
    public void setUp() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-postconstruct-predestroy-datasource.xml");
        flagDAO = (FlagDAO) applicationContext.getBean("flagDAO");
    }
 
    @Test
    public void selectFlagTest() {
        flagDAO.selectFlag();
        System.out.println(System.getProperty("dbFlag"));
    }
 
}

Step 12. Run the above JUnit test case.

Step 13. Now Look at the console log. You will see that during startup the flag value is fetched from database.

Tags:

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials | TwitterFacebook Google PlusLinkedin | Reddit | Email Me

Leave a Reply

Your email address will not be published. Required fields are marked *