Spring Bean life cycle learning

Article reference address , supplemented and optimized some content

1 Overview

  1. What is Bean

Objects called beans are the backbone of the application and are managed by the Spring IoC container. A bean is an object that is instantiated, assembled, and managed by the Spring IoC container.

  1. The way to create Bean

Spring provides xml configuration, annotation configuration or Java configuration to realize the creation and injection of Bean

  1. Relationship with IoC container

The Spring IoC (ApplicationContext) container is responsible for scanning Beans, Bean initialization, configuration and dependency management

2. Related Notes

  1. Declare Bean's annotation
  • @Component Components without a clear role
  • @Service Used in the business logic layer
  • @Repository Use in the data access layer
  • @Controller Use in the control layer
  • @RestController Essentially a combination of @Controller + @ResponseBody
  • @Configuration Component and similar , but with all @Beanannotated methods will be dynamic proxy, so the call is the same instance of the method returns
  1. other
  • @Scope Specify the scope of the Bean

    • singleton: There is one and only one Bean instance in the Spring container. As long as the Spring container does not destroy or exit, the Bean instance will always survive
    • prototype: There will be a new instance every time a Bean is obtained, and the Spring container cannot be responsible for the entire life cycle of the returned Bean instance
    • request: Request is only applicable to Web programs, each HTTP request will generate a new bean, and the bean is only valid in the current HTTP request. When the request is over, the life cycle of the object ends.
    • session: Session is only applicable to Web programs. The scope of session means that a new bean will be generated for each HTTP request, and the bean is only valid in the current HTTP session.
    • application: Application only applies to Web programs, global scope
  • @Bean Method-level beans are generally used with @Configuration. By default, the beanName is the same as the method name

  • @PostConstruct Specify initMethod, corresponding to init-method in XML configuration

  • @PreDestroy Specify destroyMethod, corresponding to destroy-method in XML configuration

3. Bean's life cycle

Macroscopically speaking, the life cycle of a Bean is divided into: definition, initialization, use, and destruction. From the code point of view, it is as follows.

flow chart

Insert picture description here

Sequence Diagram

Insert picture description here

4. Demo

The demo involves the code of five modules, namely Spring boot class, Bean object, BeanFactoryPostProcessor, BeanPostProcessor, InstantiationAwareBeanPostProcessorAdapter

4.1 User.java
@Component
public class User implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
    
    
    private String name;

    private BeanFactory beanFactory;
    private String beanName;

    public User() {
    
    
        System.out.println("【构造器】调用User的构造器实例化");
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        System.out.println("【注入属性】注入属性name");
        this.name = name;
    }

    /**
     * 通过<bean>的init-method属性指定的初始化方法
     */
    @PostConstruct
    public void userInit() {
    
    
        System.out.println("【init-method】调用<bean>的init-method属性指定的初始化方法");
    }

    /**
     * 这是BeanFactoryAware接口方法
     *
     * @param beanFactory
     */
    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
    
    
        System.out.println("【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()");
        this.beanFactory = beanFactory;
    }

    /**
     * 这是BeanNameAware接口方法
     *
     * @param beanName
     */
    @Override
    public void setBeanName(String beanName) {
    
    
        System.out.println("【BeanNameAware接口】调用BeanNameAware.setBeanName()");
        this.beanName = beanName;
    }

    /**
     * 这是InitializingBean接口方法
     */
    @Override
    public void afterPropertiesSet() {
    
    
        System.out.println("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");
    }

    /**
     * 这是DisposableBean接口方法
     */
    @Override
    public void destroy() {
    
    
        System.out.println("【DisposableBean接口】调用Disposable.destroy()");
    }

    /**
     * 通过<bean>的destroy-method属性指定的初始化方法
     */
    @PreDestroy
    public void userDestroy() {
    
    
        System.out.println("【destroy-method】调用<bean>的destroy-method属性指定的初始化方法");
    }

    @Override
    public String toString() {
    
    
        final StringBuilder sb = new StringBuilder("User{");
        sb.append("name='").append(name).append('\'');
        sb.append('}');
        return sb.toString();
    }
}
4.2 MyBeanFactoryPostProcessor.java
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    
    public MyBeanFactoryPostProcessor() {
    
    
        super();
        System.out.println("这是BeanFactoryPostProcessor实现类构造器");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) {
    
    
        System.out.println("BeanFactoryPostProcessor调用postProcessBeanFactory方法");
        BeanDefinition bd = arg0.getBeanDefinition("user");
        bd.getPropertyValues().addPropertyValue("name", "picheng");
    }
}
4.3 MyBeanPostProcessor.java
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    
    
    public MyBeanPostProcessor() {
    
    
        super();
        System.out.println("这是BeanPostProcessor实现类构造器!");
    }

    @Override
    public Object postProcessAfterInitialization(Object arg0, String arg1) {
    
    
        System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!");
        return arg0;
    }

    @Override
    public Object postProcessBeforeInitialization(Object arg0, String arg1) {
    
    
        System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!");
        return arg0;
    }
}
4.4 MyInstantiationAwareBeanPostProcessor.java
@Component
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
    
    
    public MyInstantiationAwareBeanPostProcessor() {
    
    
        super();
        System.out.println("这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!!");
    }

    /**
     * 接口方法、实例化Bean之前调用
     */
    @Override
    public Object postProcessBeforeInstantiation(Class beanClass,
                                                 String beanName) {
    
    
        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法");
        return null;
    }

    /**
     * 接口方法、实例化Bean之后调用
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
    
    
        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法");
        return bean;
    }

    /**
     * 接口方法、设置某个属性时调用
     */
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    
    
        System.out.println("InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法");
        return pvs;
    }
}
4.5 DemoApplication.java
@SpringBootApplication
public class DemoApplication {
    
    

    public static void main(String[] args) {
    
    
        System.out.println("现在开始初始化容器");

        ApplicationContext context = SpringApplication.run(DemoApplication.class, args);
        System.out.println("容器初始化成功");
        // get user,并使用
        User user = context.getBean("user", User.class);
        System.out.println(user);

        System.out.println("现在开始关闭容器!");
        ((ConfigurableApplicationContext) context).close();
    }
}
4.6 Run the program and view the results

Due to the large number of printed logs, only important information is intercepted

现在开始初始化容器

// Porcessor初始化
这是BeanFactoryPostProcessor实现类构造器
BeanFactoryPostProcessor调用postProcessBeanFactory方法
这是BeanPostProcessor实现类构造器!
这是InstantiationAwareBeanPostProcessorAdapter实现类构造器!

// Bean初始化
InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation方法
【构造器】调用User的构造器实例化
InstantiationAwareBeanPostProcessor调用postProcessPropertyValues方法
【注入属性】注入属性name
【BeanNameAware接口】调用BeanNameAware.setBeanName()
【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()
BeanPostProcessor接口方法postProcessBeforeInitialization对属性进行更改!
【init-method】调用<bean>的init-method属性指定的初始化方法
【InitializingBean接口】调用InitializingBean.afterPropertiesSet()
BeanPostProcessor接口方法postProcessAfterInitialization对属性进行更改!
InstantiationAwareBeanPostProcessor调用postProcessAfterInitialization方法
容器初始化成功

// Bean使用
User{
    
    name='picheng'}

// Bean销毁
现在开始关闭容器!
【destroy-method】调用<bean>的destroy-method属性指定的初始化方法
【DisposableBean接口】调用Disposable.destroy()

Guess you like

Origin blog.csdn.net/Dkangel/article/details/108201709