天天看點

Spring之SpringBean的生命周期詳解

前言:bean的生命周期:指  bean建立——初始化——銷毀  的過程

下面先給出我的參考答案,具體分析請看下文詳解:

Spring Bean生命周期為:
1、執行個體化BeanFactoryPostProcessor實作類
2、執行BeanFactoryPostProcessor的postProcessBeanFactory方法
3、執行個體化BeanPostProcessor實作類
4、執行個體化InstantiationAwareBeanPostProcessor實作類
5、執行InstantiationAwareBeanPostProcessor的postProcessorBeforeInstantiation方法
6、執行Bean的構造方法
7、執行InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法

8、為Bean注入屬性

9、調用BeanNameAware的setBeanName方法
10、調用BeanFactoryAware的setBeanFactory方法
11、執行BeanFactoryProcessor的postProcessorBeforeInitlalization方法
12、執行InitializingBean的afterPropertiesSet方法
13、調用<bean>的init-method屬性指定的初始化方法
14、執行BeanPostProcessor的postProcessAfterinitialization方法
15、執行InstantiationAwareBeanPostProcessor的postProcessAfterinitialization方法

16、容器初始化成功,執行業務代碼後,下面開始銷毀容器

17、調用DisposibleBean的Destory方法
18、調用<bean>的destroy-method屬性指定的初始化方法      

通過一段代碼的運作結果闡述Spring Bean的Cyclelife的過程,最後結合源代碼對SpringBean生命周期進行文字性總結。

本文代碼github連結:​​GitHub - FumingcAI666/spring-demo: 實作Spring Bean生命周期,實作Spring AOP,實作Spring IOC,實作SpringMVC​​

首先配合此段代碼先有個宏觀性(建立、初始化、銷毀)認識:

測試代碼:

package cn.spring.cyclelife;

import cn.spring.bean.FmcBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author macFmc
 * @date 2019/10/9-17:50
 */
public class TestCyclelife {
    public static void main(String[] args) {
        System.out.println("--------------【初始化容器】---------------");

        ApplicationContext context = new ClassPathXmlApplicationContext("META-INF/beandemo.xml");
        System.out.println("-------------------【容器初始化成功】------------------");
        //得到studentBean,并顯示其資訊
        FmcBean fmcBean = context.getBean("fmcBean", FmcBean.class);
        System.out.println(fmcBean);

        System.out.println("--------------------【銷毀容器】----------------------");
        ((ClassPathXmlApplicationContext) context).registerShutdownHook();
    }
}      

測試Bean例類:中的 ​

​myInit()​

​ 和 ·myDestroy()· 方法供我們在配置檔案中通過init-method和destroy-method屬性進行指定。

package cn.spring.bean;

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;

/**
 * 測試生命周期的Bean
 *
 * @author macFmc
 * @date 2019/10/9-17:45
 */
public class FmcBean implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware {
    private String name;
    private int age;
    /**
     * 實作了BeanNameAware接口,Spring可以将BeanName注入該屬性中
     */
    private String beanName;
    /**
     * 實作了BeanFactory接口,Spring可将BeanFactory注入該屬性中
     */
    private BeanFactory beanFactory;

    public FmcBean() {
        System.out.println("【Bean構造方法】學生類的無參構造方法");
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("FmcBean{");
        sb.append("name='").append(name).append('\'');
        sb.append(", age=").append(age);
        sb.append(", beanName='").append(beanName).append('\'');
        sb.append(", beanFactory=").append(beanFactory);
        sb.append('}');
        return sb.toString();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("【set注入】注入學生的name屬性");
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        System.out.println("【set注入】注入學生的age屬性");
        this.age = age;
    }

    /**
     * 自己編寫的初始化方法
     */
    public void myInit() {
        System.out.println("【init-method】調用init-method屬性配置的初始化方法");
    }

    /**
     * 自己編寫的銷毀方法
     */
    public void myDestroy() {
        System.out.println("【destroy-method】調用destroy-method屬性配置的銷毀方法");
    }

    /**
     * BeanFactoryAware接口的方法
     *
     * @param beanFactory
     * @throws BeansException
     */
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
        System.out.println("【BeanFactoryAware接口】調用BeanFactoryAware的setBeanFactory方法得到beanFactory引用");
    }

    /**
     * BeanNameAware接口的方法
     *
     * @param name
     */
    @Override
    public void setBeanName(String name) {
        this.beanName = name;
        System.out.println("【BeanNameAware接口】調用BeanNameAware的setBeanName方法得到Bean的名稱");
    }

    /**
     * InitializingBean接口的方法
     *
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("【InitializingBean接口】調用InitializingBean接口的afterPropertiesSet方法");
    }

    /**
     * DisposableBean接口的方法
     *
     * @throws Exception
     */
    @Override
    public void destroy() throws Exception {
        System.out.println("【DisposableBean接口】調用DisposableBean接口的destroy方法");
    }
}      

實作BeanPostProcessor接口:

package cn.spring.cyclelife;

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

/**
 * Bean的後置處理器
 *
 * @author macFmc
 * @date 2019/10/9-22:24
 */
public class MyBeanPostProcessor implements BeanPostProcessor {
    public MyBeanPostProcessor() {
        System.out.println("【BeanPostProcessor接口】調用BeanPostProcessor的構造方法");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("【BeanPostProcessor接口】調用postProcessBeforeInitialization方法,這裡可對" + beanName + "的屬性進行更改。");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("【BeanPostProcessor接口】調用postProcessAfterInitialization方法,這裡可對" + beanName + "的屬性進行更改。");
        return bean;
    }
}      

實作InstantiationAwareBeanPostProcessor接口:為了程式設計友善我們直接通過繼承Spring中已經提供的一個實作了該接口的擴充卡類InstantiationAwareBeanPostProcessorAdapter來進行測試。

package cn.spring.cyclelife;

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

import java.beans.PropertyDescriptor;

/**
 * 執行個體化Bean後置處理器
 * <p>
 * 一般情況下,當我們需要實作InstantiationAwareBeanPostProcessor接口時,
 * 是通過繼承Spring架構中InstantiationAwareBeanPostProcessor接口實作類
 * InstantiationAwareBeanPostProcessorAdapter這個擴充卡類來簡化我們實作接口的工作
 *
 * @author macFmc
 * @date 2019/10/9-22:26
 */
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
    public MyInstantiationAwareBeanPostProcessor() {
        System.out.println("【InstantiationAwareBeanPostProcessor接口】調用InstantiationAwareBeanPostProcessor構造方法");
    }

    /**
     * 執行個體化Bean之前調用
     */
    @Override
    public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
        System.out.println("【InstantiationAwareBeanPostProcessor接口】調用InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法");
        return null;
    }

    /**
     * 執行個體化Bean之後調用
     */
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("【InstantiationAwareBeanPostProcessor接口】調用InstantiationAwareBeanPostProcessor接口的postProcessAfterInitialization方法");
        return bean;
    }

    /**
     * 設定某個屬性時調用
     */
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
            throws BeansException {
        System.out.println("【InstantiationAwareBeanPostProcessor接口】調用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法");
        return pvs;
    }
}      

BeanFactoryPostProcessor接口:

package cn.spring.cyclelife;

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;

/**
 * BeanFactory的後置處理器
 *
 * @author macFmc
 * @date 2019/10/9-22:28
 */
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    public MyBeanFactoryPostProcessor() {
        System.out.println("【BeanFactoryPostProcessor接口】調用BeanFactoryPostProcessor實作類構造方法");
    }

    /**
     * 重寫BeanFactoryPostProcessor接口的postProcessBeanFactory方法,可通過該方法對beanFactory進行設定
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
            throws BeansException {
        System.out.println("【BeanFactoryPostProcessor接口】調用BeanFactoryPostProcessor接口的postProcessBeanFactory方法");
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("fmcBean");
        beanDefinition.getPropertyValues().addPropertyValue("age", "21");
    }
}      

Spring配置檔案beans.xml:

<?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"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">

    <!--配置Bean的後置處理器-->
    <bean id="beanPostProcessor" class="cn.spring.cyclelife.MyBeanPostProcessor">
    </bean>

    <!--配置instantiationAwareBeanPostProcessor-->
    <bean id="instantiationAwareBeanPostProcessor" class="cn.spring.cyclelife.MyInstantiationAwareBeanPostProcessor">
    </bean>

    <!--配置BeanFactory的後置處理器-->
    <bean id="beanFactoryPostProcessor" class="cn.spring.cyclelife.MyBeanFactoryPostProcessor">
    </bean>
    
    <bean id="fmcBean" class="cn.spring.bean.FmcBean" init-method="myInit"
          destroy-method="myDestroy" scope="singleton">
        <property name="name" value="FuMingCai"></property>
        <property name="age" value="21"></property>
    </bean>
</beans>      

運作結果:

Spring之SpringBean的生命周期詳解

下面根據運作結果與資料進行總結:

Spring Bean生命周期為:

1、執行個體化BeanFactoryPostProcessor實作類

2、執行BeanFactoryPostProcessor的postProcessBeanFactory方法

3、執行個體化BeanPostProcessor實作類

4、執行個體化InstantiationAwareBeanPostProcessor實作類

5、執行InstantiationAwareBeanPostProcessor的postProcessorBeforeInstantiation方法

6、執行Bean的構造方法

7、執行InstantiationAwareBeanPostProcessor的postProcessPropertyValues方法

8、為Bean注入屬性

9、調用BeanNameAware的setBeanName方法

10、調用BeanFactoryAware的setBeanFactory方法

11、執行BeanFactoryProcessor的postProcessorBeforeInitlalization方法

12、執行InitializingBean的afterPropertiesSet方法

13、調用<bean>的init-method屬性指定的初始化方法

14、執行BeanPostProcessor的postProcessAfterinitialization方法

15、執行InstantiationAwareBeanPostProcessor的postProcessAfterinitialization方法