Understanding Spring Bean Lifecycle with Practical Examples

Introduction

In this article, we'll explore the lifecycle of a Spring bean through hands-on coding examples. Understanding bean lifecycle is crucial in Spring framework as it helps in managing bean initialization, configuration, and destruction effective.

Implementing Lifecycle Interfaces

We'll create a class that implements several Spring lifecycle interfaces to observe the execution sequence of each method.


package com.example.spring.service;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class BeanLifecycle implements BeanFactoryAware, BeanNameAware,
        InitializingBean, DisposableBean, ApplicationContextAware {

    private String name;

    public String getName() {
        System.out.println("getName name=" + name);
        return name;
    }

    public void setName(String name) {
        System.out.println("setName name=" + name);
        this.name = name;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean.afterPropertiesSet()");
    }

    @Override
    public void setBeanName(String beanName) {
        System.out.println("BeanNameAware.setBeanName");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryAware.setBeanFactory");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean.destroy");
    }

    public void customInit() {
        System.out.println("Custom init method specified in XML");
    }

    public void customDestroy() {
        System.out.println("Custom destroy method specified in XML");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware.setApplicationContext");
    }
}

Implementing InstantiationAwareBeanPostProcessor

This interface extends BeanPostProcessor and provides additional hooks during bean instantiation process.


package com.example.spring.service;

import java.beans.PropertyDescriptor;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;

public class CustomInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInstantiation");
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInstantiation");
        return true;
    }

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        System.out.println("postProcessPropertyValues");
        return pvs;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization");
        return bean;
    }
}

Impleemnting BeanPostProcessor


package com.example.spring.service;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class CustomBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor - before initialization");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeanPostProcessor - after initialization");
        return bean;
    }
}

Implementing BeanFactoryPostProcessor


package com.example.spring.service;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryPostProcessor.postProcessBeanFactory");
    }
}

Spring Configuration

We'll define our beans in XML configuration 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.xsd">

    <bean id="beanPostProcessor" class="com.example.spring.service.CustomBeanPostProcessor"/>
    <bean id="instantiationAwareProcessor" class="com.example.spring.service.CustomInstantiationAwareBeanPostProcessor"/>
    <bean id="beanFactoryPostProcessor" class="com.example.spring.service.CustomBeanFactoryPostProcessor"/>
    
    <bean id="lifecycleBean" class="com.example.spring.service.BeanLifecycle" 
          init-method="customInit" destroy-method="customDestroy">
        <property name="name" value="initialValue"/>
    </bean>
</beans>

Main Application

Finally, we'll run our application to observe the lifecycle methods in action:


package com.example.spring.app;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.example.spring.service.BeanLifecycle;

public class SpringLifecycleApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        
        BeanLifecycle bean = context.getBean("lifecycleBean", BeanLifecycle.class);
        bean.setName("newValue");
        System.out.println("Current name: " + bean.getName());
        
        ((ClassPathXmlApplicationContext) context).registerShutdownHook();
    }
}

Tags: Spring Framework Bean Lifecycle Dependency Injection java XML Configuration

Posted on Thu, 01 Oct 2026 16:42:09 +0000 by chrisC