• 【Spring的Bean】生命周期、原理_Spring01


    先看图:
    在这里插入图片描述

    容器启动做的三件事:

    • 类加载生成class
    • class 变成 beanDefinition
    • beanDefinition变成bean(实例化)

    1、第一种理解:

    1)容器的启动阶段:

    (1)配置元信息

    • xml配置文件,或者是其他形式的例如properties的磁盘文件,也可以是现在主流的注解,甚至是直接的代码硬编码;

    (2)BeanDefination

    • 在内存中表示这些配置元信息的方式就是BeanDefination

    (3)BeanDefinationReader

    • BeanDefinationReader的作用就是加载配置元信息,并将其转化为内存形式的BeanDefination

      • 读取xml配置元信息,那么可以使用XmlBeanDefinationReader

      • 读取properties配置文件,那么可以使用PropertiesBeanDefinitionReader

        • 读取注解配置元信息,那么可以使用 AnnotatedBeanDefinitionReader

    (4)BeanDefinationRegistry

    • Spring通过BeanDefinationReader将配置元信息加载到内存生成相应的BeanDefination之后,就将其注册到BeanDefinationRegistry中,BeanDefinationRegistry就是一个存放BeanDefination的大篮子,它也是一种键值对的形式

    (5)BeanFactoryPostProcessor

    • BeanFactoryPostProcessor是容器启动阶段Spring提供的一个扩展点,主要负责对注册到BeanDefinationRegistry中的一个个的BeanDefination进行一定程度上的修改与替换。
    2)Bean的实例化阶段:
      1. 实例化bean:用反射的方式生成对象加肉:1. 实现的方式,通过反射)
      1. 填充bean的属性:填充属性的方法populateBean(),循环依赖的问题(三级缓存)加肉:1. 方法名称对上、2. 循环依赖问题)
      1. 调用aware接口相关的方法:invokeAwareMethod()(这个方法主要完成BeanName,BeanFactory,BeanClassLoader对象的属性设置,就做这几件事)(加肉:invokeAwareMethod这个方法主要是做了什么)
      1. 调用BeanPostProcessor中的前置处理方法:使用比较多的有ApplicationContextPostProcessor()(它是设置ApplicationContext,Environment,ResourceLoader,EmbeddValueResolver等对象)(加肉:前置处理都干了啥)
      1. 调用initmethod方法:invokeInitmethod(),这个方法里面判断是否实现了initializingBean接口,如果有,调用afterPropertiesSet方法,没有就不调用。
      1. 调用BeanPostProcessor的后置处理方法:著名的spring的aop就是在此处实现的,在AbstractAutoProxyCreator里面实现的。
      1. 获取到完整的对象:可以通过getBean的方式来进行对象的获取。
      1. 销毁流程:1.判断是否实现了DispoableBean接口,2.调用destroyMethod方法。
    • ps:在表述的时候不要只说图中有的关键点,要学会加肉。


    另一种说法

    bean的实例化和初始化:

    将spring容器启动分为三个阶段:(1)容器初始化阶段、(2)Bean实例化(instantiation)阶段、(3)Bean初始化(initialization)阶段。

    • 容器初始化阶段:这个阶段主要是通过某些工具类加载Configuration MetaData,并将相关信息解析成BeanDefinition注册到BeanDefinitionRegistry中,即对象管理信息的收集。同时也会进行各种处理器的注册、上下文的初始化、事件广播的初始化等等准备工作。
    • Bean实例化(instantiation)阶段:这个阶段主要是Bean的实例化,其实就是Bean对象的构造。不过此时构造出的对象,他们内部的依赖对象仍然没有注入,只是通过反射(或Cglib)生成了具体对象的实例(执行构造函数),其实有点类似于我们手动new对象,new出的对象已经执行过了构造函数,并且内部的基本数据也已经准备好了,但如果内部还有其他对象的依赖,就需要后续的流程去主动注入。
      new出的对象已经执行过了构造函数,并且内部的基本数据也已经准备好了,但如果内部还有其他对象的依赖,就需要后续的流程去主动注入。
    • Bean初始化(initialization)阶段:这个阶段主要是对实例化好后的Bean进行依赖注入的过程。同时还会执行用户自定义的一些初始化方法,注册Bean的销毁方法、缓存初始化好的Bean等。
  • 相关阅读:
    茴香豆的“茴”有四种写法,Python的格式化字符串也有
    Windows中Jenkins安装与配置
    【计算机组成原理】寄存器的本质——锁存器
    [附源码]java毕业设计实践教学管理系统
    谷歌翻译不用代理可用的免费api python版本亲测可用
    零基础Linux_20(进程信号)内核态和用户态+处理信号+不可重入函数+volatile
    全栈自动化测试之python基础类的自定义属性访问及动态属性设置
    判断一个类是否为另一类的子类issubclass()
    Spark rdd之mappartition妙用
    知识图谱1(实体抽取)
  • 原文地址:https://blog.csdn.net/weixin_38963649/article/details/127108658