Skip to main navigation Skip to main content Skip to page footer

Spring Core - BeanFactoryPostProcessor and BeanPostProcessor

| Java Spring Boot

Both BeanFactoryPostProcessor and BeanPostProcessor are used for modifying beans in the Spring lifecycle, but they operate at different stages and serve different purposes.

1. BeanFactoryPostProcessor

A BeanFactoryPostProcessor allows you to modify the bean definitions before the beans are instantiated. It operates at the container configuration stage. It can modify the properties of BeanDefinition objects (metadata about beans, not the actual beans).

Create a BeanFactoryPostProcessor Implementation

First we create our class MyBean and afterwards a BeanFactoryPostProcessor implementation, which “wraps”  the class it. When the application starts, MyBeanFactoryPostProcessor modifies the name property of the MyBean before it is instantiated.

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

// Sample Bean
@Component
public class MyBean {
    private String name = "Default Name";

    public void setName(String name) {
        this.name = name;
    }

    public void printName() {
        System.out.println("Bean Name: " + name);
    }
}

// BeanFactoryPostProcessor
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

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

       // Modify a bean definition before the bean is instantiated
       if (beanFactory.containsBeanDefinition("myBean")) {
           var beanDefinition = beanFactory.getBeanDefinition("myBean");
           beanDefinition.getPropertyValues().add("name", "Updated Bean Name");
       }
   }
}

2. BeanPostProcessor

A BeanPostProcessor allows you to modify beans after they are instantiated but before and after initialization (e.g., before and after @PostConstruct or init-method execution). It is typically used for cross-cutting concerns like logging, proxying, or security.

Create a BeanPostProcessor Implementation

After having defined the bean that we want to possibly modify we create the BeanPostProcessor. As seen in the code example below, it has two methods that we want to overwrite:

  • postProcessBeforeInitialization: makes changes to the bean before initialization
  • postProcessAfterInitialization: makes changes to the bean after initialization


After running the output should contain the following lines:

Before Initialization: myBean
MyBean: Inside init method
After Initialization: myBean

import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

// Sample Bean
@Component
public class MyBean {
    private String name = "Default Name";

    public void setName(String name) {
        this.name = name;
    }

    public void printName() {
        System.out.println("Bean Name: " + name);
    }

    public void init() {
        System.out.println("MyBean: Inside init method");
    }
}

// BeanPostProcessor
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        if (bean instanceof MyBean) {
            System.out.println("Before Initialization: " + beanName);
        }
        return bean; // Return the (possibly modified) bean
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if (bean instanceof MyBean) {
            System.out.println("After Initialization: " + beanName);
        }
        return bean; // Return the (possibly modified) bean
    }
}

@Configuration
public class AppConfig {
    @Bean(initMethod = "init")
    public MyBean myBean() {
        return new MyBean();
    }
}

Summary of Their Differences

FeatureBeanFactoryPostProcessorBeanPostProcessor
PurposeModify bean definitions before beans are instantiatedModify actual bean instances during initialization
Execution PhaseBefore bean instantiation (container setup)During bean initialization (after instantiation)
ScopeOperates on BeanDefinitionOperates on actual bean instances
Use CaseModify metadata (e.g., properties) for beans globallyApply cross-cutting logic to beans (e.g., proxies)

When to Use

  • Use BeanFactoryPostProcessor for modifying bean definitions, such as injecting property values dynamically or altering scope definitions.
  • Use BeanPostProcessor for bean instance-level logic, such as adding custom behaviors, logging, or proxies.
Back