【Spring】Bean life cycle

Based on the latest Spring framework tutorial of [Power Node], the first Spring 6 tutorial on the entire network, learn spring from scratch to advanced with Lao Du and Lao Du’s original notes https://www.yuque.com/docs/share/866abad4-7106 -45e7-afcd-245a733b073f?# "Spring6" is organized, document password: mg9b


Spring related articles are compiled and summarized at: https://www.yuque.com/u27599042/zuisie


What is Bean life cycle

  • The life cycle of a bean is: the whole process of the object from creation to final destruction, what process does the bean object go through from creation to destruction
    • When are Bean objects created?
    • What method will be called before and after creating the Bean object?
    • When is the Bean object destroyed?
    • What methods are called before and after the Bean object is destroyed?
  • Spring is actually a factory that manages Bean objects. It is responsible for object creation and object destruction.

Why you need to know the life cycle of Bean

  • The essence of the life cycle is: which method of which class is called at which time node.
  • We need to fully understand the special time nodes in this lifeline, and which method of which class will be called at these special nodes.
  • We may need to execute a specific piece of code at a special point in time. Only if we know where the special time nodes are and what methods will be called at that special node can we determine where the code is written. This code You can put it on this node, and when the lifeline comes here, it will naturally be called.

5 steps of Bean life cycle

  • For the management of the Bean life cycle, you can refer to the source code of Spring: the doCreateBean() method of the AbstractAutowireCapableBeanFactory class.
  • The Bean life cycle can be roughly divided into five major steps:
    • Step 1: Instantiate the Bean and call the parameterless constructor to create the object
    • Step 2: Assign values ​​to Bean attributes, call the set method of the object, and perform set injection.
    • Step 3: Initialize the Bean and call the init method of the Bean (this method needs to be written by yourself and then configured)
    • Step 4: Use Beans
    • Step 5: Destroy the Bean and call the Bean's Destroy method (this method needs to be written by yourself and then configured)
      • To destroy the Bean, the Spring container must be closed. The Bean will not be destroyed until the Spring container is closed.

Bean preparation

package cw.spring.study.pojo;

/**
 * ClassName: User
 * Package: cw.spring.study.pojo
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-26 17:21
 * @Version 1.0
 */
public class User {
    
    
    private String name;
    
    public User() {
    
    
        System.out.println("1. User 无参构造方法执行");
    }
    
    public void setName(String name) {
    
    
        this.name = name;
        System.out.println("2. User setName 方法执行");
    }
    
    public void init() {
    
    
        System.out.println("3. User init 方法执行,进行 Bean 的初始化");
    }
    
    public void destroy() {
    
    
        System.out.println("5. User destroy 方法执行,进行 Bean 的销毁");
    }
}

Bean configuration

<!-- 
  手动指定Bean的初始化方法和销毁方法
    init-method 属性
        配置 Bean 的初始化方法
    destroy-method
        配置 Bean 的销毁方法
-->
<bean id="user" class="cw.spring.study.pojo.User" init-method="init" destroy-method="destroy">
  <property name="name" value="张三"/>
</bean>

test

@org.junit.Test
public void testUser() {
    
    
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    User user = applicationContext.getBean("user", User.class);
    System.out.println("4. User Bean 的使用," + user);
    // 进行Bean的销毁,必须关闭Spring容器,只有关闭了Spring容器,Bean才会进行销毁
    // ApplicationContext 接口中无关闭容器的方法,ClassPathXmlApplicationContext 中有声明定义
    ClassPathXmlApplicationContext context = (ClassPathXmlApplicationContext) applicationContext;
    // 关闭容器
    context.close();
}

image.png

7 steps of Bean life cycle

  • The seven-step Bean life cycle is compared to the five-step Bean life cycle. Two steps are added before and after initializing the Bean.
  • In the above five steps, the third step is to initialize the Bean. The methods executed before and after initialization are the before and after methods of the "Bean post-processor". Through the "Bean post-processor" we can initialize the Bean before and after Add the code that needs to be executed.
  • To add a "Bean post-processor" a class needs to implement the BeanPostProcessor class and override the before and after methods.
  • 7 steps of Bean life cycle:
    • Step 1: Instantiate the Bean
    • Step 2: Bean attribute assignment
    • Step 3: Execute the before method of "Bean post-processor".
    • Step 4: Initialize the Bean
    • Step 5: Execute the after method of "Bean post-processor".
    • Step 6: Use Beans
    • Step 7: Destroy the Bean

Create a Bean postprocessor

package cw.spring.study.pojo;

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

/**
 * ClassName: LogBeanPostProcessor
 * Package: cw.spring.study.pojo
 * Description:
 * 日志Bean后处理器,
 * 在Bean对象的初始化前后执行相应的代码
 *
 * @Author tcw
 * @Create 2023-05-27 10:26
 * @Version 1.0
 */
public class LogBeanPostProcessor implements BeanPostProcessor {
    
    
    /**
     * 初始化Bean之前执行的代码
     *
     * @param bean 刚创建的Bean
     * @param beanName Bean的名字
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    
    
        System.out.println("日志 Bean 后处理器的 before 方法执行...");
        // return 不要修改
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    
    
        System.out.println("日志 Bean 后处理器的 after 方法执行...");
        // return 不要修改
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

Configure Bean Postprocessor

  • Configure the bean post-processor in the Spring configuration file
  • After the Bean post-processor is configured, it will act on the life cycle of each Bean in the entire configuration file. For example, the Bean post-processor configured in the spring.xml file will act on all Beans in the current configuration file.
<!-- 
  配置 Bean 后处理器
  将会作用于本配置文件中所有Bean对象的生命周期中 
-->
<bean class="cw.spring.study.pojo.LogBeanPostProcessor"/>

test

image.png

Ten steps of the Bean life cycle

  • There are three more steps in the Bean life cycle than ten steps:
    • Point 1: Before the "Bean post-processor" before method, after the Bean attribute assignment
    • Point 2: After the "Bean post-processor" before method, before the initialization of the Bean
    • Point 3: After using the Bean, or before destroying the Bean
  • The characteristics of these three added points are to check whether your Bean implements certain specific interfaces. If it implements these interfaces, the Spring container will call the methods in this interface.

Implement Aware related interfaces

  • Aware related interfaces include: BeanNameAware, BeanClassLoaderAware, BeanFactoryAware
    • When a bean implements BeanNameAware, Spring will pass the bean's name to the bean.
    • When a Bean implements BeanClassLoaderAware, Spring will pass the class loader that loads the Bean to the Bean.
    • When a Bean implements BeanFactoryAware, Spring will pass the Bean factory object to the Bean.
  • Before the "Bean post-processor" before method, it will check whether the Bean implements the Aware-related interfaces, and if the interfaces are implemented, the methods in these interfaces will be called. The purpose of calling these methods is to pass some data to you to make it more convenient for you to use.
package cw.spring.study.pojo;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;

/**
 * ClassName: User
 * Package: cw.spring.study.pojo
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-26 17:21
 * @Version 1.0
 */
public class User implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {
    
    
    private String name;
    
    public User() {
    
    
        System.out.println("1. User 无参构造方法执行");
    }
    
    public void setName(String name) {
    
    
        this.name = name;
        System.out.println("2. User setName 方法执行");
    }
    
    public void init() {
    
    
        System.out.println("4. User init 方法执行,进行 Bean 的初始化");
    }
    
    public void destroy() {
    
    
        System.out.println("7. User destroy 方法执行,进行 Bean 的销毁");
    }
    
    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
    
    
        System.out.println("User Bean 的类加载器:" + classLoader);
    }
    
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    
    
        System.out.println("生产 User Bean 的工厂:" + beanFactory);
    }
    
    @Override
    public void setBeanName(String name) {
    
    
        System.out.println("User Bean 的名字为:" + name);
    }
}

image.png

Implement the InitializingBean interface

  • Before the Bean is initialized, check whether the Bean implements the InitializingBean interface, and if so, call the methods in the interface.
  • The method of InitializingBean is executed earlier than the init-method.
public class User implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean {
    
    
	...

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

image.png

Implement the DisposableBean interface

  • Before destroying the Bean, check whether the Bean implements the DisposableBean interface, and if so, call the methods in the interface.
  • DisposableBean's method is executed earlier than destroy-method
public class User implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware,
                    InitializingBean, DisposableBean {
    
    
	...

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

    // 之前销毁Bean的方法与DisposableBean接口中的方法重名,
    // 进行销毁方法名的修改,并修改Spring.xml文件中的配置
    public void myDestroy() {
    
    
        System.out.println("7. User destroy 方法执行,进行 Bean 的销毁");
    }

	...

}

image.png

Beans have different scopes and different management methods

  • Spring will choose the management method based on the scope of the bean.
  • For beans with singleton scope, Spring can accurately know when the bean is created, when it is initialized, and when it is destroyed; for beans with prototype scope, Spring is only responsible for creating, when the container creates an instance of the bean Finally, the Bean is initialized, and after the client program obtains the Bean, the Bean instance is handed over to the client code for management, and the Spring container will no longer track its life cycle.
  • The Spring container only manages the complete life cycle of singleton beans. For prototype beans, Spring only performs partial life cycle management.
<?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 后处理器 -->
	<bean class="cw.spring.study.pojo.LogBeanPostProcessor"/>
	
	<bean 
			id="user" 
			class="cw.spring.study.pojo.User" 
			init-method="init" 
			destroy-method="myDestroy"
			scope="prototype"
	>
		<property name="name" value="张三"/>
	</bean>
	
</beans>

image.png

Hand over your new object to Spring for management

  • Sometimes we may encounter such a requirement that a java object is our own new, and then we want this object to be managed by the Spring container
public class Student {
    
    }
@org.junit.Test
public void testRegisterBean() {
    
    
    Student student = new Student();
    System.out.println(student);
    
    // 将自己new的对象交给Spring进行管理
    // 使用DefaultListableBeanFactory对象进行Bean实例的注册
    DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
    // 将自己new的对象注册到Spring容器中
    factory.registerSingleton("student", student);
    
    // 从Spring容器中获取Bean
    System.out.println(factory.getBean("student"));
}

image.png

Guess you like

Origin blog.csdn.net/m0_53022813/article/details/132058599