In this tutorial I will show you how we can use @PostConstruct and @PreDestroy annotation in Spring framework. @PostConstruct and @PreDestroy annotations are generally considered best practices for receiving life cycle callbacks in a modern Spring application. Using these annotations means that our beans are not coupled to Spring specific interfaces.

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.


Eclipse 2019-12, Java at least 1.8, Spring Boot 2.3.1, MySQL 8.0.17

Setup Project

Create either gradle or maven based project in Eclipse. The name of the project is spring-postconstruct-predestroy.

If you create gradle based project then use below build.gradle script:

buildscript {
	ext {
		springBootVersion = '2.3.1.RELEASE'
    repositories {
    dependencies {

plugins {
    id 'java-library'
    id 'org.springframework.boot' version "${springBootVersion}"

sourceCompatibility = 12
targetCompatibility = 12

repositories {

dependencies {
	//required for jdk 9 or above

If you create maven based project then use below pom.xml file:

<project xmlns=""




		<!--required only if jdk 9 or higher version is used-->

					<source>at least 8</source>
					<target>at least 8</target>

MySQL Table

To query MySQL database we need to create a table under roytuts database as shown below:

  `flag_id` int unsigned NOT NULL AUTO_INCREMENT,
  `flag_val` varchar(30) NOT NULL,
  PRIMARY KEY (`flag_id`)

INSERT INTO flag(flag_id, flag_val) values(1, 'true');

Database Configuration

To establish database connection we need to have the following standard configuration in a file called under classpath folder src/main/resources.


Java configuration for database related beans:

package com.roytuts.spring.postconstruct.predestroy.config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;

public class Config {

	private Environment environment;

	public DataSource dataSource() {
		return DataSourceBuilder.create().driverClassName(environment.getProperty("spring.datasource.driverClassName"))

	public JdbcTemplate jdbcTemplate(DataSource dataSource) {
		return new JdbcTemplate(dataSource);


POJO Class

The POJO class will map the table data with the Java class.

package com.roytuts.spring.postconstruct.predestroy.dto;

public class Flag {

	private Integer flagId;
	private String flagVal;



Repository Class

Repository class is responsible for interacting with database for required activities:

package com.roytuts.spring.postconstruct.predestroy.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

public class FlagDao {

	private JdbcTemplate jdbcTemplate;

	private final String SQL_SELECT_FLAG_VAL = "select flag_val from flag where flag_id = 1";

	public String getFlag() {
		return jdbcTemplate.queryForObject(SQL_SELECT_FLAG_VAL, new Object[] {}, String.class);


Service Class

Service class is responsible for performing necessary business processing.

package com.roytuts.spring.postconstruct.predestroy.service;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.roytuts.spring.postconstruct.predestroy.dao.FlagDao;

public class FlagService {

	private FlagDao flagDao;

	public void doFlagWork() {
		System.out.println("Do Flag Work");

	@PostConstruct // do some initialization work
	public void selectFlag() {
		String val = flagDao.getFlag();

	@PreDestroy // do some destruction work (like releasing pooled connections)
	public void cleanFlag() {
		System.setProperty("dbFlag", "false");
		System.out.println("DB Flag: " + System.getProperty("dbFlag"));

	private void setDbFlag(String dbFlag) {
		System.setProperty("dbFlag", dbFlag);
		System.out.println("DB Flag: " + System.getProperty("dbFlag"));


Main Class

A class is having main method with @SpringBootApplication annotation will run the application.

package com.roytuts.spring.postconstruct.predestroy;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.roytuts.spring.postconstruct.predestroy.service.FlagService;

public class SpringPostConstructPreDestroyApp implements CommandLineRunner {
	private FlagService flagService;

	public static void main(String[] args) {, args);

	public void run(String... args) throws Exception {
		System.out.println("DB Flag in System Property: " + System.getProperty("dbFlag"));

Testing the Application

Executing the above main class will give you the following output:

DB Flag: true
Do Flag Work
DB Flag in System Property: true
DB Flag: false

Look at the above output, we set the DB flag into System property after fetching from the database table once FlagService bean is created.

Also notice that just before the bean gets destroyed the DB flag is set to false.

Source Code


Thanks for reading.


Leave a Reply

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