In Spring, beans are the most basic objects and everything is done around them. Spring is a Bean Oriented Programming (BOP) framework. Beans function in BOP much like objects in OOP. Given this importance, we first need to understand what exactly is a Bean?

What is a Bean

First, let’s look at the definition of beans in the Spring documentation:

In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application

From the above, we can define a Bean: a Bean is an object instantiated, assembled, and managed by IOC.

The life cycle of the Bean

We need to be clear that the life cycle of our Bean here refers primarily to the Singleton Bean. In the case of the Prototype Bean, the IOC container no longer manages the current instance when the user getBean obtains the prototype Bean instance. Instead, the user gets the management, and getBean generates a new instance. For request/session/application/websocket this several scope bean we don’t talk about here.

The Bean life cycle starts at different times in different containers. For ApplicationContext, the bean is instantiated when the container is started. In the case of the BeanFactory, it is not instantiated until the getBean() method is called.

We know that for ordinary Java objects, their life cycle is

  • instantiation
  • When it is no longer in use, it is collected through the garbage collection mechanism

This is not the case with beans. The Bean life cycle is shown in the following figure

For the above methods, we can divide them into the following categories

  1. The Bean's own methodsSuch as constructors, getters/setters, and methods specified by init-method and destory-method
  2. Bean-level lifecycle methods: Can be understood as Bean classes directly implement interface methods, such as BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean, These methods only apply to the current Bean
  3. Container-level methods (BeanPostProcessor series of interfaces): after mainly handler method, such as above InstantiationAwareBeanPostProcessor, BeanPostProcessor interface methods. The implementation classes for these interfaces are bean-independent and registered with the Spring container. These post-handlers come into play whenever the Spring container creates any beans.
  4. Factory Post-processor approach (BeanFactoryProcessor series of interfaces): including AspectJWeavingEnabler, CustomAutowireConfigurer, ConfigurationClassPostProcessor, etc. These are beanFactoryPostProcessors already implemented in the Spring framework to implement specific functionality.

The Bean’s own methods and bean-level lifecycle methods work only on the current Bean, but container-level lifecycle methods and post-factory processor methods work on all beans

1, 2, and 4 are all fairly well understood, so let’s focus on what are BeanPostProcessor and BeanFactoryPostProcessor

In my personal understanding, BeanPostProcessor and BeanFactoryPostProcessor are extension points created by Spring, where users can create their own implementation classes to modify beans or BeanFactory

Note that for the ApplicatonContext, the container can automatically detect and load BeanPostProcessor and BeanFactoryPostProcessor, but the BeanFactory can’t and needs to be registered manually by calling its own methods. There can be more than one BeanPostProcessor and BeanFactoryPostProcessor. ApplicationContext can also according to the org. Springframework. Core. PriorityOrdered and org., springframework. Core. The Ordered for custom sorting, But the BeanFactory can’t. The default order is the order of registration.

Here are two confusing words:

  • InstantiationInstantiate, which means invokeThe constructorInstantiate
  • InitializationInitialization, as in the Bean’s declaration cycleinit-methodThe specified method orInitializingBean.afterPropertiesSet()methods

Here are some examples of commonly used interfaces:

Common Interfaces

  1. BeanNameAware The interface has only one method, setBeanName(String Name), to get the id or name of the bean

  2. BeanFactoryAware This interface has only one method, setBeanFactory(BeanFactory BeanFactory), to get the BeanFactory in the current environment

  3. ApplicationContextAware This interface has only one method setApplicationContext(ApplicationContext ApplicationContext), To get the ApplicationContext in the current environment

    Once you get the IOC container, you can modify the Beans and so on

  4. InitializingBean The interface has only one method, afterPropertiesSet(), which is called after property injection is complete

  5. DisposableBean This interface has only one method destroy(), called when the container is destroyed, before the user-specified destroy-method

  6. BeanPostProcessor This interface has two methods:

  • PostProcessBeforeInitialization (Object beans, String beanName) : inBefore initializationCalling this method
  • PostProcessAfterInitialization (Object beans, String beanName) : inAfter initializationCalling this method

We know from method signatures that we can use beanName to filter out beans that we need to personalize

  1. InstantiationAwareBeanPostProcessor class is the BeanPostProcessor interface, commonly used has the following three methods
  • PostProcessBeforeInstantiation (Class beanClass, String beanName) : in the beanBefore instantiationcall
  • PostProcessProperties (PropertyValues PVS, Object Bean, String beanName) : In the beanAfter instantiation, before setting propertiescall
  • PostProcessAfterInstantiation (Class beanClass, String beanName) : in the BeanAfter instantiationcall

Test the Bean life cycle

Let’s write an example to verify the Bean life cycle we mentioned above

First, we create a new User, which implements our BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean interfaces

Then we implement our own BeanPostProcessor

Implement your own InstantiationAwareBeanPostProcessor

The XML configuration file is as follows

<context:component-scan base-package="com.xiaohuan.springtest"/>



<bean id="user" class="com.xiaohuan.springtest.beanlifecycle.User" init-method="myInit" destroy-method="myDestroy">

    <! Constructor injection -->

    <constructor-arg index="0" type="int">

        <value>1</value>

    </constructor-arg>

    <constructor-arg index="1" type="java.lang.String">

        <value>xiaohuan</value>

    </constructor-arg>



    <! -- setmethod injection -->

    <property name="id" value="2"/>

    <property name="name" value="dahuan"/>

</bean>

Copy the code

Write our own test classes

Last run project