海哥聊架构 潜水
  • 1发帖数
  • 1主题数
  • 0关注数
  • 0粉丝
开启左侧

Spring之Bean生命周期源码解析

[复制链接]
海哥聊架构 发表于 2021-9-15 14:40:10 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
Bean的生命周期

Spring最重要的功能就是帮助程序员创建对象(也就是IOC),而启动Spring就是为创建对象做准备,所以我们要先明白Spring到底是怎么去创建Bean的,也就是先弄明白Bean的生命周期。
Bean的生命周期是指:在SpringBean中,一个Bean是如何生成、如何烧毁的。
Bean的生命周期流程如下图所示:

                               
登录/注册后可看大图


  • 注册BeanDefinition
  • 合并BeanDefinition
  • 加载类
  • 实例化前处理
  • 推断构造函数
  • 实例化
  • BeanDefinition后置处理
  • 属性填充
  • 执行Aware
  • 初始化前置处理
  • 初始化
  • 初始化后置处理
  • 注册烧毁接口
1.注册BeanDefinition

BeanDefinition是什么

BeanDefinition中存在许多属性用来描述一个Bean的特点,好比:

  • beanClassName,表示Bean范例名称
  • scope,表示Bean作用域
  • lazyInit,表示该Bean是否懒加载
  • initMethodName,表示初始化方法名字
  • destroyMethodName,表示烧毁方法名字
  • constructorArgumentValues,表示构造器参数值
  • 还有许多...
为什么需要BeanDefinition

Spring IOC容器本质上是一个ConcurrentHashMap,key为Bean的Name,Value为Bean的实例对象。

                               
登录/注册后可看大图

大概你会说,我通过反射机制实例化一个目标对象,以Bean范例名称为key,目标对象为value,存入IOC容器中,不就可以了吗?Spring为什么要搞这么复杂?
我想,Spring之所以如许计划的目标,是可定制性及扩展性。Spring作为一个容器框架,通过IOC(控制反转)和DI(依赖注入)实现Bean之间依赖关系的管理以及Bean的生命周期管理。要实现Bean依赖关系的管理,必然要辨认出依赖关系,并把这些信息保存下来以供创建Bean实例时使用 ;要实现Bean的生命周期管理,必然要辨认出Bean有哪些生命周期扩展点以及每个扩展点的处理逻辑,并把这些信息保存下来以供创建Bean实例时使用。
这些信息可以看作是Bean的元数据信息,它们应该保存在哪儿呢?
说到这儿,你应该已经恍然大悟了,这些元数据信息就保存在BeanDefinition中,这些元数据信息将会用于指导Bean的创建及生命周期管理。
怎么注册BeanDefinition

在Spring中,我们经常会通过以下几种方式来界说Bean


  • @Bean
  • @Component(@Service,@Controller等)
这些,我们可以称之为声明式界说Bean
我们还可以编程式界说Bean,即直接通过BeanDefinition,好比:

                               
登录/注册后可看大图

我们还可以通过BeanDefinition设置Bean的其他属性,好比:

                               
登录/注册后可看大图

2.合并BeanDefinition

通过扫描得到所有BeanDefinition之后,就可以根据BeanDefinition创建Bean对象了,但是在Spring中支持父子BeanDefinition。
父子BeanDefinition实际用的比较少,使用是如许的,好比:
这么界说的环境下,child是单例Bean。
但是这么界说的环境下,child就是原型Bean了。
由于child的父BeanDefinition是parent,所以会继承parent上所界说的scope属性,当然,其他属性也会继承。而在根据child来生成Bean对象之前,需要进行BeanDefinition的合并,得到完整child的BeanDefinition。
3.加载类

BeanDefinition合并之后,就可以先去创建Bean对象了,而创建Bean就必须先实例化对象,而实例化就必须先加载BeanDefinition中对应的class,在AbstractAutowireCapableBeanFactory类的createBean方法中,一开始就会调用:
Class resolvedClass = resolveBeanClass(mbd, beanName);这行代码就是去加载类,方法是这么实现的:
if (mbd.hasBeanClass()) {    return mbd.getBeanClass();}if (System.getSecurityManager() != null) {    return AccessController.doPrivileged((PrivilegedExceptionAction

精彩评论1

oniubi 发表于 2021-9-16 01:45:04 | 显示全部楼层
转发了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

猜你喜欢
在线客服邮箱
wxcy#wkgb.net

邮箱地址#换为@

Powered by 创意电子 ©2018-现在 专注资源实战分享源码下载站联盟商城