Spring 4.x source code series 5-bean life cycle

1. Frontier

After learning bean creation and bean loading , we have learned about the management of managed object beans by the Spring IOC container, and the life cycle of the bean is also completely managed by the Spring IOC container. Spring's ioc container is very powerful, responsible for the creation and management of Spring's Beans. The Spring bean is a very important part of the entire Spring application. Understanding the life cycle of Spring Bean will be of great help for us to understand the entire spring framework.

BeanFactory and ApplicationContext are two very important containers in Spring. Their functions are as follows:

BeanFactory : provides the creation bean and dependency injection support

ApplicationContext : In addition to the functions of BeanFactory , some extended functions have been added, such as event propagation , resource access and internationalized message access .

The completed life cycle of the bean is shown in the following figure:

The following describes the life cycle of the bean of the ApplicationContext and BeanFactory containers respectively

Two, ApplicationContext Bean life cycle

First look at the life cycle diagram of the ApplicationContext Bean, as shown below:

ApplicationContext container, the life cycle process of Bean is roughly as follows:

2.1 instantiate bean (create bean instance BeanWrapper)

For the ApplicationContext container, when the container is started, it will instantiate all beans, and the container will instantiate it by obtaining the information in the BeanDefinition (bean definition) object. Note that this step is just a simple instantiation, without initialization and dependency injection. The created bean instance is packaged into a BeanWrapper object. The BeanWrapper provides an interface for setting object properties, thus avoiding the use of reflection mechanisms to set bean properties.

2.2 Fill in properties (initialize bean properties)

The instantiated object BeanWrapper is in a native state at this time, and no property settings have been performed, including dependency injection. Then Spring will perform dependency injection based on the information in the BeanDefinition.
And complete dependency injection through the attribute setting interface provided by BeanWrapper

2.3 Inject xxxAware interface

Spring will detect whether the object implements the xxxAware interface, and inject the relevant xxxAware instance into the bean, as shown below:

1) If the Bean implements the BeanNameAware interface, it will call the setBeanName method of the interface and pass in the id of the Bean, so that the Bean gets its own id in the configuration file

2) If the Bean implements the BeanFactoryAware interface, the setBeanFactory method of the interface will be passed into the BeanFactory of the Bean, so that the Bean will obtain the BeanFactory object it is in

3) If the Bean implements the ApplicationContextAware interface, it will call the setApplicationContext method of the interface and pass in the ApplicationContext of the Bean, so that the Bean gets its own ApplicationContext object

2.4 BeanPostProcessor interface

After the above three steps, the bean object has been constructed. If you want to do some custom processing before the object is used, you can complete the processing by implementing the BeanPostProcessor interface, which provides two important methods:

postProcessBeforeInitialization( Object bean, String beanName ): Pass in the bean and beanName that are currently being initialized, and you can customize the bean at this time. Since this method will be executed before the InitialzationBean interface method, it is called pre-processing

postProcessAfterInitialization( Object bean, String beanName ): Pass in the bean and beanName that are currently being initialized, and you can customize the bean at this time. Since this method will be executed after the InitialzationBean interface method is called, it is called post-processing

2.5 InitialzationBean interface and init-method method

After the pre-processing of BeanPostProcessor, if the bean implements the InitialzationBean interface, the afterPropertiesSet method of the InitializingBean interface will be called

The InitializingBean interface has only one method, afterPropertiesSet(), which does not have any parameters, so it cannot do any processing on the bean, but it can implement some additional business logic

In order to reduce the intrusion of the client code, Spring also provides the init-method attribute for the configuration of the bean, through which the user can configure the method that he wants to execute

After this step, the bean can be used formally. For a bean whose scope is a singleton type, the instance of the bean will be cached in the Spring IOC container, and for a bean whose scope is a prototype type, a new one will be created every time it is called Object, its life cycle is handed over to the caller to manage, and it is no longer managed by the Spring container

2.6 DisposableBean interface and destroy-meythod method

After the container is closed, if the Bean implements the DisposableBean interface, the destroy method of the interface will be called to destroy the bean

Similarly, in order to reduce the intrusion of the client code, Spring also provides the destroy-method attribute for the configuration of the bean, through which the user can configure the method to be executed after the bean is destroyed

At this point, the life cycle of the entire Bean ends

demo example

1), custom BeanPostProcessor, the code is as follows:

 

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

/**
 * 自定义BeanPostProcessor
 *
 * @date 2019-12-24 11:23
 **/
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean,
                                                  String beanName) throws BeansException {
        System.out.println("BeanPostProcessor postProcessBeforeInitialization 方法被调用");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean,
                                                 String beanName) throws BeansException {
        System.out.println("BeanPostProcessor postProcessAfterInitialization 方法被调用");
        return bean;
    }
}

2), TestBean entity class, the code is as follows:

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;

/**
 * 测试bean
 *
 * @date 2019-12-24 11:17
 **/
public class TestBean implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {
    private String beanName;
    private BeanFactory beanFactory;
    private ApplicationContext applicationContext;

    public TestBean() {
        System.out.println("TestBean 构造方法被调用");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryAware 的 setBeanFactory 方法被调用");
        this.beanFactory = beanFactory;
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("BeanNameAware 的 setBeanName 方法被调用");
        this.beanName = name;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware 的 setApplicationContext 方法被调用");
        this.applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean 的 afterPropertiesSet 方法被调用");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean 的 destroy 方法被调用");
    }

    public void myInitMethod(){
        System.out.println("自定义的 myInitMethod 方法被调用");
    }

    public void myDestroyMethod(){
        System.out.println("自定义的 myDestroyMethod 方法被调用");
    }
}

3) The test code is as follows:

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * ApplicationContext测试
 *
 * @date 2019-12-24 11:31
 **/
public class ApplicationContextTest {
    public static void main(String[] args) {
        System.out.println("开始初始化ApplicationContext容器");
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application_context.xml");
        System.out.println("ApplicationContext容器初始化完毕");
        applicationContext.close();
    }
}

4) The content of the src/test/resources/application_context.xml configuration file is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "https://www.springframework.org/dtd/spring-beans-2.0.dtd">

<beans>

	<!-- 自定义BeanPostProcessor -->
	<bean id="myBeanPostProcessor" class="com.springboot.demo.bean.MyBeanPostProcessor"/>

	<!-- 测试bean -->
	<bean id="testBean" class="com.springboot.demo.bean.TestBean" init-method="myInitMethod" 
		  destroy-method="myDestroyMethod"/>
</beans>

5) The running results are as follows:

开始初始化ApplicationContext容器
TestBean 构造方法被调用
BeanNameAware 的 setBeanName 方法被调用
BeanFactoryAware 的 setBeanFactory 方法被调用
ApplicationContextAware 的 setApplicationContext 方法被调用
BeanPostProcessor postProcessBeforeInitialization 方法被调用
InitializingBean 的 afterPropertiesSet 方法被调用
自定义的 myInitMethod 方法被调用
BeanPostProcessor postProcessAfterInitialization 方法被调用
ApplicationContext容器初始化完毕
DisposableBean 的 destroy 方法被调用
自定义的 myDestroyMethod 方法被调用

It can be seen from the running result that it is consistent with the process on the life cycle diagram of the ApplicationContext Bean

Three, BeanFactory Bean life cycle

The life cycle diagram of BeanFactory Bean is as follows:

As can be seen from the above figure, the life cycle of BeanFactory Bean and the life cycle steps of ApplicationContext Bean are basically the same. The similarities are not repeated here, and only the differences are analyzed below:

1) The BeanFactory container will not call the setApplicationContext method of the ApplicationContextAware interface

2) The postProcessBeforeInitialzation method and postProcessAfterInitialization method of the BeanPostProcessor interface will not be called automatically, even if the BeanPostProcessor is configured in the xml, it is useless, and you must manually register it through the code.

3) When the BeanFactory container is started, it will not instantiate all beans , including all beans whose scope is singleton and are not lazy loaded, but they are instantiated when they are called (getBean method call)

demo example

The contents of the custom BeanPostProcessor, TestBean and configuration file are all unchanged, only the test class is modified, as shown below:

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

import com.springboot.demo.bean.MyBeanPostProcessor;

/**
 * BeanFactory测试
 *
 * @date 2019-12-24 14:17
 **/
public class BeanFactoryTest {
    public static void main(String[] args) {
        System.out.println("开始初始化BeanFactory容器");
        ConfigurableBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("application_context.xml"));
        System.out.println("BeanFactory容器初始化完毕");
        // 这里必须手动注册 BeanPostProcessor
        beanFactory.addBeanPostProcessor(new MyBeanPostProcessor());
        // 必须调用 BeanFactory 的 getBean 方法,不然 bean 是不会实例化的,因为 BeanFactory 中的 bean 都是懒加载
        beanFactory.getBean("testBean");
        beanFactory.destroySingletons();
    }
}

The results of the operation are as follows:

开始初始化BeanFactory容器
BeanFactory容器初始化完毕
TestBean 构造方法被调用
BeanNameAware 的 setBeanName 方法被调用
BeanFactoryAware 的 setBeanFactory 方法被调用
BeanPostProcessor postProcessBeforeInitialization 方法被调用
InitializingBean 的 afterPropertiesSet 方法被调用
自定义的 myInitMethod 方法被调用
BeanPostProcessor postProcessAfterInitialization 方法被调用
DisposableBean 的 destroy 方法被调用
自定义的 myDestroyMethod 方法被调用

It can be seen from the running result that it is consistent with the process on the life cycle diagram of the BeanFactory Bean

Four, summary

For the life cycle management of Beans, there are ApplicationContext and BeanFactory. Spring recommends that you use the ApplicationContext method to obtain beans . The BeanFactory method has been abandoned by Spring. It is not recommended that you use the BeanFactory method to obtain beans.

reference:

https://www.jianshu.com/p/3944792a5fff

https://www.zhihu.com/question/38597960

Guess you like

Origin blog.csdn.net/ywlmsm1224811/article/details/103669833