preface

In the next few articles, I will record some knowledge about Spring, which is also my study notes for learning About Spring. In this article, I will first look at the life cycle of Spring beans.

I. Flow chart of life cycle

The full life cycle of a Spring Bean, which starts with the creation of the Spring container and ends with the destruction of the Bean by the Spring container, contains a number of key points.





Classification of various interface methods

The full life cycle of a Bean goes through various method calls, which can be divided into the following categories:
1. The Bean’s own methods:This includes methods called by the Bean itself and methods specified by init-method and destroy-method in the < Bean > configuration file

Bean-level lifecycle interface methods: This includes methods of the BeanNameAware, BeanFactoryAware, InitializingBean, and DiposableBean interfaces

Level 3, container lifecycle interface methods: this includes InstantiationAwareBeanPostProcessor and BeanPostProcessor these two interface implementation, general said their implementation class for the “processor”.

4, factory after processor interface methods: this includes AspectJWeavingEnabler ConfigurationClassPostProcessor, CustomAutowireConfigurer etc. Very useful plant after processor interface methods. The post-factory processor is also container-level. Called immediately after the application context assembs the configuration file.

Three, presentations,

Let’s demonstrate the Spring Bean lifecycle with a simple Spring Bean.

1. Start with a simple Spring Bean that calls the Bean’s own methods and bean-level lifecycle interface methods. For demonstration purposes, It implements BeanNameAware, BeanFactoryAware, InitializingBean, and DiposableBean. It also has two methods, which correspond to the init-method and destroy-method of

in the configuration file. As follows:

package com.study.vo;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;

public class Person implements BeanFactoryAware.BeanNameAware.InitializingBean.DisposableBean {

    private String name;
    private String address;
    private int phone;

    private BeanFactory beanFactory;
    private String beanName;

    public Person(a) {
        System.out.println([constructor] calls constructor instantiation of Person);
    }

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        System.out.println([Injection property] Injection property name);
        this.name = name;
    }

    public String getAddress(a) {
        return address;
    }

    public void setAddress(String address) {
        System.out.println([add attribute] Add attribute address);
        this.address = address;
    }

    public int getPhone(a) {
        return phone;
    }

    public void setPhone(int phone) {
        System.out.println("[Injection properties] Inject property phone");
        this.phone = phone;
    }

    @Override
    public String toString(a) {
        return "Person [address=" + address + ", name=" + name + ", phone=" + phone + "]";
    }

    // This is the BeanFactoryAware interface method
    @Override
    public void setBeanFactory(BeanFactory arg0) throws BeansException {
        System.out.println("Call BeanFactoryAware BeanFactoryAware interface 】 【. SetBeanFactory ()");
        this.beanFactory = arg0;
    }

    // This is the BeanNameAware interface method
    @Override
    public void setBeanName(String arg0) {
        System.out.println("Call BeanNameAware BeanNameAware interface 】 【. SetBeanName ()");
        this.beanName = arg0;
    }

    // This is the InitializingBean interface method
    @Override
    public void afterPropertiesSet(a) throws Exception {
        System.out.println("Call InitializingBean InitializingBean interface 】 【. AfterPropertiesSet ()");
    }

    // This is the DiposibleBean interface method
    @Override
    public void destroy(a) throws Exception {
        System.out.println(Call diposiblebean.destory ());
    }

    // The initialization method specified by the init-method attribute
    public void myInit(a) {
        System.out.println("The initialization method specified by the init-method property of the call to [init-method]");
    }

    // The initialization method specified by the destroy-method attribute
    public void myDestory(a) {
        System.out.println("Destroy-method" specifies the initialization method specified by the destroy-method attribute of the call.); }}Copy the code


2. Here is how to demonstrate the BeanPostProcessor interface:

package com.study.vo;

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

public class MyBeanPostProcessor implements BeanPostProcessor {

    public MyBeanPostProcessor(a) {
        super(a); System.out.println("This is the BeanPostProcessor implementation class constructor!!");
        // TODO Auto-generated constructor stub
    }

    @Override
    public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeansException {
        System.out.println("Call methods BeanPostProcessor interface 】 【 postProcessAfterInitialization to attribute changes!");
        return arg0;
    }

    @Override
    public Object postProcessBeforeInitialization(Object arg0, String arg1) throws BeansException {
        System.out.println("Call methods BeanPostProcessor interface 】 【 postProcessBeforeInitialization to attribute changes!");
        returnarg0; }}Copy the code
As above, the BeanPostProcessor interface includes two methods postProcessAfterInitialization and postProcessBeforeInitialization, the first parameter to these two methods are to be processed Bean objects, The second argument is the name of the Bean. The return values are also the Bean objects to process. Be careful here.


3. InstantiationAwareBeanPostProcessor interface is essentially the BeanPostProcessor interface, Normally we inherit the Spring with the Adapter class InstantiationAwareBeanPostProcessor Adapter to use it, as follows:

package com.study.vo;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;

import java.beans.PropertyDescriptor;

public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {

    public MyInstantiationAwareBeanPostProcessor(a) {
        super(a); System.out.println("This is InstantiationAwareBeanPostProcessorAdapter implementation class constructor!!");
    }

    // interface method before instantiating the Bean
    @Override
    public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor postProcessBeforeInstantiation calling");
        return null;
    }

    // interface method, after instantiating the Bean
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor postProcessAfterInitialization calling");
        return bean;
    }

    // called when the interface method is set to a property
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        System.out.println("InstantiationAwareBeanPostProcessor postProcessPropertyValues calling");
        returnpvs; }}Copy the code

The three methods, including the second method postProcessAfterInitialization is to rewrite the BeanPostProcessor method. Third method postProcessPropertyValues used to operation properties, the return value should also be PropertyValues object.




4. Demonstrate the post-factory processor interface method as follows:

package com.study.vo;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    public MyBeanFactoryPostProcessor(a) {
        super(a); System.out.println("This is the BeanFactoryPostProcessor implementation class constructor!!");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) throws BeansException {
        System.out.println("[BeanFactoryPostProcessor interface] call postProcessBeanFactory);
        BeanDefinition bd = arg0.getBeanDefinition("person");
        bd.getPropertyValues().addPropertyValue("phone"."110"); }}Copy the code



ApplicationContext. XML is a very simple configuration file. Using applicationContext, the handler does not need to register manually:

<? The XML version = "1.0" encoding = "utf-8"? > <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="beanPostProcessor" class="com.study.vo.MyBeanPostProcessor"> </bean> <bean id="instantiationAwareBeanPostProcessor" class="com.study.vo.MyInstantiationAwareBeanPostProcessor"> </bean> <bean id="beanFactoryPostProcessor" class="com.study.vo.MyBeanFactoryPostProcessor"> </bean> <bean id="person" class="com.study.vo.Person" Init-method ="myInit" destroy-method="myDestory" scope="singleton" p:name=" "p:phone="159000000" /> </beans>Copy the code



Write a test class

package com.study;

import com.study.vo.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {
        System.out.println("Now initialize the container.");

        ApplicationContext factory = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("Container initialization successful");
        // Get Preson and use it
        Person person = factory.getBean("person", Person.class);
        System.out.println(person);
        System.out.println("Now close the container!"); ((ClassPathXmlApplicationContext) factory).registerShutdownHook(); }}Copy the code



The results



summary

By analyzing the results, we can know the spring initialization process. By writing such a demo, we can have a deeper understanding of the life cycle of Spring beans