Spring源码分析-Bean生命周期概述

Spring源码分析系列

Spring源码分析-启动流程浅析
Spring源码分析-BeanDefinition
Spring源码分析-Bean管理查找与注册(1)
Spring源码分析-Bean管理查找与注册(2)
Spring源码分析-Bean管理循环依赖和三级缓存
Spring源码分析-Bean生命周期概述
Spring源码分析-Bean生命周期createBean


文章目录

  • Spring源码分析系列
  • 前言
  • 一、bean的生命周期
    • 1.1、普通java对象生命周期
    • 1.2、spring bean生命周期
      • 1.2.1、spring bean生命周期
      • 1.2.2、spring bean生命周期再扩展
    • 1.3、小结
  • 二、验证
    • 2.1、Bean对象
    • 2.2、BeanPostProcessor
    • 2.3、配置文件与main方法
  • 三、InitializingBean
  • 四、BeanPostProcessor
  • 五、总结


前言

由于bean的生命周期内容比较多,会分成多个博客进行分析,如果哪里介绍的不周,希望多多指出。


一、bean的生命周期

1.1、普通java对象生命周期

一个普通java对象生命周期基本就是:实例化 --> 属性赋值 --> 对象应用 --> gc回收 。这就是一个对象生命周期最基本的形态,在怎么扩展也不会跳出这圈的

1.2、spring bean生命周期

那么4个阶段哪些阶段可以进行扩展呢?一一进行分析:
1)实例化,这个阶段是jvm操作,直接向操作系统申请内存,这个阶段是肯定不行的
2)销毁,这个阶段也是jvm操作,对象已经要销毁了就没有必要扩展了,但是在销毁前是可以做一些操作
3)对象应用,这个阶段已经在使用对象也没有必要扩展,但是在使用前是可以做一些操作
4)属性赋值,这个阶段前后都可以进行扩展,属性赋值前可操作性不大

1.2.1、spring bean生命周期

实例化 --> 属性赋值 --> bean初始化过程 --> 对象应用 --> bean销毁过程 --> gc回收
注意:初始化和销毁,其实对应的就是init-method,destroy-method两个方法
然而spring并不止是这样的,还有更细化的流程,这个流程就需要有代码支撑

1.2.2、spring bean生命周期再扩展

虽然spring进行生命周期的扩展,但仍然不足以满足业务需求,所以spring进行再次扩展后,再扩展后生命周期变为:实例化 -->属性赋值–> bean后置处理器的before方法 --> 属性后置处理afterPropertiesSet --> bean初始化过程 --> bean后置处理器的after方法 --> 对象应用 --> bean销毁过程 --> gc回收

1.3、小结

bean的生命周期阶段很多,但是不要死记硬背,还是需要理解才能牢记于心。上面是我总结的整个过程,我认为是比较清晰的

二、验证

2.1、Bean对象

一个普通类,没有任何注解标准,只实现了接口InitializingBean

public class Orders implements InitializingBean {
    private String oname;

    public Orders() {
        System.out.println("第一步,执行Orders无参数构造");
    }

    public void setOname(String oname) {
        this.oname = oname;
        System.out.println("第二步,Set方法");
    }

    //接口InitializingBean的抽象方法
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("第四步,AfterProperties方法");
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("第三步, postConstruct --> BeanPostProcessor before方法");
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("第六步, preDestroy --> BeanPostProcessor before方法");
    }

    public void initMethod() {
        System.out.println("第五步,initMethod方法");
    }

    public void destroyMethod() {
        System.out.println("第七步,destroyMethod方法");
    }

    @Override
    public String toString() {
        return "Orders{" +
                "oname='" + oname + '\'' +
                '}';
    }
}

2.2、BeanPostProcessor

//需要注册到spring容器中
public class MyBeanProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //这里根据bean类型,做一些特殊操作
        /*
         *  if (bean instance XXX && beanName.startsWith("AAA")) {
         *   //进行增强处理
         *   return bean;
         * } else {
         *   //do nothing
         *   return bean;
         * }
         */
        System.out.println("第三步,后置处理器前置方法");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("第六步,后置处理器后置方法");
        return bean;
    }
}

2.3、配置文件与main方法


<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
       https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="order" class="com.worker.Orders" init-method="initMethod" destroy-method="destroyMethod">
        <property name="oname" value="xuxb"/>
    bean>
    
    <bean id="myBeanProcessor" class="com.worker.MyBeanProcessor"/>
beans>
public static void main(String[] args) {
    try {
         GenericApplicationContext context = new AnnotationConfigApplicationContext("com.worker");
         Orders order = context.getBean("myOrders", Orders.class);
         System.out.println("对象应用----->");
         System.out.println(order.toString());
         System.out.println("<-----对象应用");
         context.registerShutdownHook();
     } catch (Exception e) {
         System.out.println(e);
     }
}

输出结果:

> Task :spring-study-01:WApp.main()
第一步,执行Orders无参数构造
第二步,Set方法
第三步,后置处理器前置方法
第四步,AfterProperties方法
第五步,initMethod方法
第六步,后置处理器后置方法
对象应用----->
Orders{oname='xuxb'}
<-----对象应用
第七步,destroyMethod方法

三、InitializingBean

public interface InitializingBean {
	void afterPropertiesSet() throws Exception;
}

实现这个接口后,就可以对当前bean进行扩展,需要记住:只对当前bean有效

四、BeanPostProcessor

BeanPostProcessor也是一个接口,实现这个接口的类,必须作为组件Component注册到spring ioc容器中,才能对其他bean进行扩展,需要注意:该接口对所有的bean都生效

public interface BeanPostProcessor {
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}
}

五、总结

本篇博客,从原理和代码上,只说明了一个重点:bean的生命周期。这个知识点在面试中也会经常问到,希望能帮助大家

你可能感兴趣的:(Spring家族,spring,bean生命周期)