Spring中Bean的生命周期

Spring中的Bean的生命周期

1. 什么是Spring中Bean的生命周期

Spring最大的特点就是面向Bean(BOP)编程,Spring所管理的Bean是一个POJO,即简单的JavaBean(不需要实现任何规范的Bean)。Spring提供了很多方法可以对所管理的Bean对象进行功能增强,其中就包含了对生命周期的控制。

2. Bean创建前的准备阶段

在Bean被Spring创建之前,首先会实例化IoC容器,找到所有被Spring管理的Bean的配置信息。同时还会实例化BeanFactoryPostProcessor、InstantiationAwareBeanPostProcessor、BeanPostProcessor等处理器。

接口说明
BeanFactoryPostProcessor该接口只有一个BeanFactoryPostProcessor()方法,在BeanFactory初始化之后可以对Bean的元数据进行修改。此时Bean还没有被实例化。
InstantiationAwareBeanPostProcessor该接口的实现类在准备阶段只会进行实例化,并不会调用任何方法。
BeanPostProcessor该接口的实现类在准备阶段只会进行实例化,并不会调用任何方法。

2.1 代码演示

package com.wxw.processor.ioc;

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 WxwBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    public WxwBeanFactoryPostProcessor() {
        System.out.println("调用【BeanFactoryPostProcessor】构造方法!!!");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("调用【BeanFactoryPostProcessor】类的postProcessBeanFactory方法!!!");
        // 在这里可以修改Bean的元数据
        BeanDefinition userBean = configurableListableBeanFactory.getBeanDefinition("userBean");
        userBean.getPropertyValues().addPropertyValue("age","28");
    }
}
package com.wxw.processor.instantiation;

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

public class WxwInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    public WxwInstantiationAwareBeanPostProcessor() {
        System.out.println("调用【InstantiationAwareBeanPostProcessor】构造方法!!!");
    }

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("调用【InstantiationAwareBeanPostProcessor】的Before方法!!!");
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("调用【InstantiationAwareBeanPostProcessor】的After方法!!!");
        return false;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        return null;
    }
}

package com.wxw.processor.initialize;

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

public class WxwBeanPostProcessor implements BeanPostProcessor {

    public WxwBeanPostProcessor(){
        System.out.println("调用【BeanPostProcessor】构造方法!!!");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("调用【BeanPostProcessor】的【Before】方法!!!");
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("调用【BeanPostProcessor】的【After】方法!!!");
        return null;
    }
}

package com.wxw.test;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestClass {

    @Test
    public void test1(){
        System.out.println("=====================IoC容器初始化begin=========================");
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        System.out.println("=====================IoC容器初始化end=========================");
    }

}

运行结果如下:

=====================IoC容器初始化begin=========================
调用【BeanFactoryPostProcessor】构造方法!!!
调用【BeanFactoryPostProcessor】类的postProcessBeanFactory方法!!!
调用【InstantiationAwareBeanPostProcessor】构造方法!!!
调用【BeanPostProcessor】构造方法!!!
=====================IoC容器初始化end=========================

2.2 时序图

在这里插入图片描述

3. Bean实例化阶段

Spring中的Bean在实例化阶段会被InstantiationAwareBeanPostProcessor处理器的相关方法进行处理。

接口说明
InstantiationAwareBeanPostProcessor该接口有3个方法:
1. postProcessBeforeInstantiation():该方法会在Bean实例化之前调用,如果该方法返回的是非空对象,则会跳过Spring创建Bean的过程(包括依赖注入、初始化等操作),直接执行BeanPostProcessor的后置处理器,然后返回这个对象。如果该方法返回为空,则执行Spring创建Bean的正常流程。

2. postProcessAfterInstantiation():该方法会在Bean实例化之后,依赖注入之前调用,如果该方法返回false,则直接退出populateBean()方法(依赖注入),使当前Bean依赖注入步骤短路。如果该方法返回true,则执行正常流程。

3. postProcessProperties():该方法在After方法返回true后执行,可以在Spring给Bean属性值设置之前,对该Bean的属性进行处理。

3.1 代码演示

package com.wxw.processor.instantiation;

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

import java.lang.reflect.Constructor;

public class WxwInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    public WxwInstantiationAwareBeanPostProcessor() {
        System.out.println("调用【InstantiationAwareBeanPostProcessor】构造方法!!!");
    }

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("调用【InstantiationAwareBeanPostProcessor】的Before方法!!!");
        Object obj = null;
        try {
            Constructor<?> constructor = beanClass.getConstructor(String.class, Integer.class);
            obj = constructor.newInstance("wxw",20);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("调用【InstantiationAwareBeanPostProcessor】的After方法!!!");
        return false;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        System.out.println("调用【InstantiationAwareBeanPostProcessor】的postProcessProperties方法!!!");
        return pvs;
    }
}
package com.wxw.pojo;

import lombok.Data;
import org.springframework.beans.factory.InitializingBean;

@Data
public class UserBean implements InitializingBean {

    private String name;
    private Integer age;

    public UserBean() {
        System.out.println("调用【UserBean】的构造方法!!!");
    }

    public UserBean(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public void setName(String name) {
        System.out.println("调用【UserBean】的【setName】方法!!!");
        this.name = name;
    }

    public void setAge(Integer age) {
        System.out.println("调用【UserBean】的【setAge】方法!!!");
        this.age = age;
    }

    @Override
    public String toString() {
        return "UserBean{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("【UserBean】的【init】方法执行!!!");
    }
}

运行结果如下:

=====================IoC容器初始化begin=========================
调用【BeanFactoryPostProcessor】构造方法!!!
调用【BeanFactoryPostProcessor】类的postProcessBeanFactory方法!!!
调用【InstantiationAwareBeanPostProcessor】构造方法!!!
调用【BeanPostProcessor】构造方法!!!
=====================IoC容器初始化end=========================
调用【InstantiationAwareBeanPostProcessor】的Before方法!!!
调用【BeanPostProcessor】的【After】方法!!!

3.2 时序图

在这里插入图片描述

4. Bean初始化阶段

在Bean初始化阶段会执行Aware接口实现类的相关方法、BeanPostProcessor处理相关的方法、InitializingBean接口的setBeanFactory方法、xml中配置的init-method方法。

接口说明
Aware实现该接口的类,会让该类感知到某些属性,比如:BeanFactoryAware、BeanNameAware等等
BeanPostProcessor该接口有2个方法:
1. postProcessBeforeInitialization:在Bean初始化回调函数之前执行
2. postProcessAfterInitialization:在Bean初始化回调函数之后执行
InitializingBeansetBeanFactory方法:Bean的初始化回调函数
init-method配置的方法与InitializingBean接口的方法一样,初始化回调函数

4.1 代码演示

UserBean类:

package com.wxw.pojo;

import lombok.Data;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;

@Data
public class UserBean implements InitializingBean, BeanFactoryAware {

    private String name;
    private Integer age;

    private BeanFactory beanFactory;

    public UserBean() {
        System.out.println("调用【UserBean】的构造方法!!!");
    }

    public UserBean(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public void setName(String name) {
        System.out.println("调用【UserBean】的【setName】方法!!!");
        this.name = name;
    }

    public void setAge(Integer age) {
        System.out.println("调用【UserBean】的【setAge】方法!!!");
        this.age = age;
    }

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

    @Override
    public String toString() {
        return "UserBean{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

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

    public void init(){
        System.out.println("【init-method】配置的【init】方法执行!!!");
    }
}

spring-config.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userBean" class="com.wxw.pojo.UserBean"
          lazy-init="true"
          init-method="init"
          scope="singleton">
        <property name="name" value="Wxw"/>
        <property name="age" value="18"/>
    </bean>

    <bean id="wxwBeanFactoryPostProcessor" class="com.wxw.processor.ioc.WxwBeanFactoryPostProcessor"></bean>

    <bean id="wxwInstantiationAwareBeanPostProcessor" class="com.wxw.processor.instantiation.WxwInstantiationAwareBeanPostProcessor"></bean>

    <bean id="wxwBeanPostProcessor" class="com.wxw.processor.initialize.WxwBeanPostProcessor"></bean>

</beans>

BeanPostProcessor实现类:

package com.wxw.processor.initialize;

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

public class WxwBeanPostProcessor implements BeanPostProcessor {

    public WxwBeanPostProcessor(){
        System.out.println("调用【BeanPostProcessor】构造方法!!!");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("调用【BeanPostProcessor】的【Before】方法!!!");
        return null;
    }

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

测试类:

package com.wxw.test;

import com.wxw.pojo.UserBean;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestClass {

    @Test
    public void test1(){
        System.out.println("=====================IoC容器初始化begin=========================");
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        System.out.println("=====================IoC容器初始化end=========================");
        UserBean userBean = (UserBean) applicationContext.getBean("userBean");
        System.out.println(userBean);
    }

}

运行结果:

=====================IoC容器初始化begin=========================
调用【BeanFactoryPostProcessor】构造方法!!!
调用【BeanFactoryPostProcessor】类的postProcessBeanFactory方法!!!
调用【InstantiationAwareBeanPostProcessor】构造方法!!!
调用【BeanPostProcessor】构造方法!!!
=====================IoC容器初始化end=========================
调用【InstantiationAwareBeanPostProcessor】的Before方法!!!
调用【UserBean】的构造方法!!!
调用【InstantiationAwareBeanPostProcessor】的After方法!!!
调用【InstantiationAwareBeanPostProcessor】的postProcessProperties方法!!!
调用【UserBean】的【setName】方法!!!
调用【UserBean】的【setAge】方法!!!
调用【BeanFactoryAware】的【setBeanFactory】方法!!!
调用【BeanPostProcessor】的【Before】方法!!!
【InitializingBean】的【init】方法执行!!!
【init-method】配置的【init】方法执行!!!
调用【BeanPostProcessor】的【After】方法!!!
UserBean{name='Wxw', age=28}

4.2 时序图

在这里插入图片描述

5. Bean销毁阶段

在Bean销毁时,会执行DisposableBean接口destroy方法、xml中配置的destroy-method方法。

5.1 代码演示

UserBean类:

package com.wxw.pojo;

import lombok.Data;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

@Data
public class UserBean implements InitializingBean, BeanFactoryAware, ApplicationContextAware, DisposableBean {

    private String name;
    private Integer age;

    private BeanFactory beanFactory;
    private ApplicationContext applicationContext;

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

    public UserBean() {
        System.out.println("调用【UserBean】的构造方法!!!");
    }

    public UserBean(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public void setName(String name) {
        System.out.println("调用【UserBean】的【setName】方法!!!");
        this.name = name;
    }

    public void setAge(Integer age) {
        System.out.println("调用【UserBean】的【setAge】方法!!!");
        this.age = age;
    }

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

    @Override
    public String toString() {
        return "UserBean{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

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

    public void init(){
        System.out.println("【init-method】配置的【init】方法执行!!!");
    }

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

    public void beanDestroy(){
        System.out.println("【destroy-method】配置的【beanDestroy】方法执行!!!");
    }
}

spring-config.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userBean" class="com.wxw.pojo.UserBean"
          lazy-init="true"
          init-method="init"
          destroy-method="beanDestroy"
          scope="singleton">
        <property name="name" value="Wxw"/>
        <property name="age" value="18"/>
    </bean>

    <bean id="wxwBeanFactoryPostProcessor" class="com.wxw.processor.ioc.WxwBeanFactoryPostProcessor"></bean>

    <bean id="wxwInstantiationAwareBeanPostProcessor" class="com.wxw.processor.instantiation.WxwInstantiationAwareBeanPostProcessor"></bean>

    <bean id="wxwBeanPostProcessor" class="com.wxw.processor.initialize.WxwBeanPostProcessor"></bean>

</beans>

测试类:

package com.wxw.test;

import com.wxw.pojo.UserBean;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestClass {

    @Test
    public void test1(){
        System.out.println("=====================IoC容器初始化begin=========================");
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        System.out.println("=====================IoC容器初始化end=========================");
        UserBean userBean = (UserBean) applicationContext.getBean("userBean");
        System.out.println(userBean);
        System.out.println("=====================IoC容器销毁begin=========================");
        applicationContext.close();
        System.out.println("=====================IoC容器销毁end=========================");
    }

}

执行结果:

=====================IoC容器初始化begin=========================
调用【BeanFactoryPostProcessor】构造方法!!!
调用【BeanFactoryPostProcessor】类的postProcessBeanFactory方法!!!
调用【InstantiationAwareBeanPostProcessor】构造方法!!!
调用【BeanPostProcessor】构造方法!!!
=====================IoC容器初始化end=========================
调用【InstantiationAwareBeanPostProcessor】的Before方法!!!
调用【UserBean】的构造方法!!!
调用【InstantiationAwareBeanPostProcessor】的After方法!!!
调用【InstantiationAwareBeanPostProcessor】的postProcessProperties方法!!!
调用【UserBean】的【setName】方法!!!
调用【UserBean】的【setAge】方法!!!
调用【BeanFactoryAware】的【setBeanFactory】方法!!!
调用【ApplicationContextAware】的【setApplicationContext】方法!!!
调用【BeanPostProcessor】的【Before】方法!!!
【InitializingBean】的【init】方法执行!!!
【init-method】配置的【init】方法执行!!!
调用【BeanPostProcessor】的【After】方法!!!
UserBean{name='Wxw', age=28}
=====================IoC容器销毁begin=========================DisposableBean】的【destroy】方法执行
【destroy-method】配置的【beanDestroy】方法执行!!!
=====================IoC容器销毁end=========================

进程已结束,退出代码为 0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值