42

I was trying to understand the difference between BeanFactoryPostProcessor and BeanPostProcessor.

I understood that BeanFactoryPostProcessor operates on bean definition i.e. before the bean instance is getting created it gets executed and BeanPostProcessor gets executed after bean is instantiated and lifecycle events are called.

Does this mean BeanFactoryPostProcessor is not a part of spring lifecycle events as it's called before instantiation while BeanPostProcessor is the part of Spring lifecycle events? Kindly verify if my understanding is right.

M. Deinum
  • 115,695
  • 22
  • 220
  • 224
jasminum
  • 471
  • 1
  • 7
  • 12

4 Answers4

71

BeanFactoryPostProcessor is an interface and beans that implement it are actually beans that undergo the Spring lifecycle (Example below) but these beans don't take part of the other declared beans' lifecycle.

public class CustomBeanFactory implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        for (String beanName : beanFactory.getBeanDefinitionNames()) {

            BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);

            // Manipulate the beanDefiniton or whatever you need to do

        }
    }
}

The differences about BeanFactoryPostProcessor and BeanPostProcessor:

  1. A bean implementing BeanFactoryPostProcessor is called when all bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for overriding or adding properties even to eager-initializing beans. This will let you have access to all the beans that you have defined in XML or that are annotated (scanned via component-scan).
  2. A bean implementing BeanPostProcessor operate on bean (or object) instances which means that when the Spring IoC container instantiates a bean instance then BeanPostProcessor interfaces do their work.
  3. BeanFactoryPostProcessor implementations are "called" during startup of the Spring context after all bean definitions will have been loaded while BeanPostProcessor are "called" when the Spring IoC container instantiates a bean (i.e. during the startup for all the singleton and on demand for the proptotypes one)
araknoid
  • 3,065
  • 5
  • 33
  • 35
  • When callback method of BeanFactoryPostProcessor is called, how does it over-rides the properties in the beans which aren't even created yet? Does this mean that it replaces the placeholders used with the actual values in the byte code loaded for the bean? – Sumit Desai Apr 25 '17 at 12:16
  • 1
    @SumitDesai As the BeanFactoryPostProcessor works only with the definition of the spring beans and not with their instances, the override of the properties in this case is useful for custom config files targeted at system administrators that override bean properties configured in the application context (as stated in the doc [BeanFactoryPostProcessor](http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/config/BeanFactoryPostProcessor.html) ). – araknoid Apr 26 '17 at 08:26
  • I understand the purpose of allowing system administrator to allow to override properties. But, my question is how BeanFactoryPostProcessor does it? Does it modify the bean definition using reflection? – Sumit Desai Apr 27 '17 at 04:47
  • 1
    Having access to the `ConfigurableListableBeanFactory beanFactory` inside the `postProcessBeanFactory` method, you can access the bean definition and its properties through `beanFactory.getBeanDefinition("yourBeanName").getPropertyValues()` and then you can add or modify them. – araknoid Apr 27 '17 at 14:38
  • But, when BeanFactoryPostProcessor is operating, the beans are not created. Does this mean that calling beanFactory.getBeanDefinition("yourBeanName") from BeanFactoryPostProcessor will create a bean immediately, without going through normal bean creation process? – Sumit Desai Apr 28 '17 at 08:58
  • 3
    `beanFactory.getBeanDefinition("yourBeanName")` gives access to the bean definition and not an instance of the bean so if you interact with only the definition of the bean (name of the bean, the class to instanciate, properties to inject, dependencies...) no beans will be created. However, if you interact with the instance of the beans, it will create one instantly without going through normal bean creation process. – araknoid May 02 '17 at 14:06
  • Ok.Got it. Thanks. – Sumit Desai May 04 '17 at 04:49
  • Does it mean that we would have one `BeanPostProcessor` per Application Context ? – Arun Jun 06 '17 at 12:30
  • @Arun You can have multiple BeanPostProcessor with different characteristic/behaviours – araknoid Jun 12 '17 at 11:58
41

Here is a flow diagram that might help to understand the spring bean initialisation life cycle.

enter image description here

As we can see, the implementation of theBeanFactoryPostProcessor is executed before any spring bean instantiation, contrary to the BeanPostprocessor, where the implemented method will be executed only when the bean is instantiated.

The source image is from the Spring 5 Design Patterns Book.

I pick the explanation from the book:

After loading the bean definitions from all styles of configurations, BeanFactoryPostProcessor comes into the picture to modify the definition of some beans, and then the container instantiates the beans. Finally, BeanPostProcessor works on the beans, and it can modify and change the bean object. This is the initialization phase.

xmen-5
  • 1,806
  • 1
  • 23
  • 44
11

Bean Factory Post Procesor (BFPP):

Used when we want to override XML / annotations, because Spring reads XML / annotations to create the beans. If you want to provide a different configuration to Spring during creation (at run time), then you need to use BFPP. Creating the internal dependency graph is a one time process.

Bean Post Processor (BPP):

The above step happened only once. It's like creating the "menu" of beans. After creating the bean, if you want to change the bean properties, you can't make any changes to the XML / annotations. Instead, you can use the BPP for bean configuration change after creation. The BPP has 2 execution areas, one before @postconstruct and one after @postconstruct.

Real Time Example:

You want to place an online food order from Zomato. While ordering online, you give a list of food (XML/annotations) to the restaurant. But, just before the restaurant starts making the food, you call them and ask them to change the dish (BFPP). Now the food is ready to be delivered and you've received it (Bean is created). But you want to make some modifications (like salt or chilly powder), and you can do this before tasting the food (because you know restaurants never put enough salt), or even after tasting the food (this is before and after @postconstruct). Once the taste is good, then the food is ready (the bean is ready to use).

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Sambeet
  • 193
  • 3
  • 10
7

The BeanFactoryPostProcessor executes before bean Object instantiation (ie at the time Applicationcontext container is initialized)

BeanPostprocessor is executed after the bean object is created, as it can be executed before init() and after init().

araknoid
  • 3,065
  • 5
  • 33
  • 35