• Spring- SpringBean生命周期源码解析


    附带资料JFR介绍:深度探索JFR - JFR详细介绍与生产问题定位落地 - 1. JFR说明与启动配置 - 知乎

    Spring最重要的功能就是帮助程序员创建对象(也就是IOC),而启动Spring就是为创建Bean对象做准备,所以我们先明白Spring到底是怎么去创建Bean的,也就是先弄明白Bean的生命周期。

    Bean的生命周期就是指在Spring中,一个Bean是如何生成的,如何销毁的

    Bean生命周期流程图:https://www.processon.com/view/link/5f8588c87d9c0806f27358c1

    Bean的生成过程

    1. 生成BeanDefinition

    Spring启动的时候会进行扫描,会先调用org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#scanCandidateComponents(String basePackage)
    扫描某个包路径,并得到BeanDefinition的Set集合。

    关于Spring启动流程,后续会单独的课详细讲,这里先讲一下Spring扫描的底层实现:

    Spring扫描底层流程:Spring扫描底层流程| ProcessOn免费在线作图,在线流程图,在线思维导图

    1. 首先,通过ResourcePatternResolver获得指定包路径下的所有.class文件(Spring源码中将此文件包装成了Resource对象)
    2. 遍历每个Resource对象
    3. 利用MetadataReaderFactory解析Resource对象得到MetadataReader(在Spring源码中MetadataReaderFactory具体的实现类为CachingMetadataReaderFactory,MetadataReader的具体实现类为SimpleMetadataReader)
    4. 利用MetadataReader进行excludeFilters和includeFilters,以及条件注解@Conditional的筛选(条件注解并不能理解:某个类上是否存在@Conditional注解,如果存在则调用注解中所指定的类的match方法进行匹配,匹配成功则通过筛选,匹配失败则pass掉。)
    5. 筛选通过后,基于metadataReader生成ScannedGenericBeanDefinition
    6. 再基于metadataReader判断是不是对应的类是不是接口或抽象类
    7. 如果筛选通过,那么就表示扫描到了一个Bean,将ScannedGenericBeanDefinition加入结果集

    MetadataReader表示类的元数据读取器,主要包含了一个AnnotationMetadata,功能有

    1. 获取类的名字、
    2. 获取父类的名字
    3. 获取所实现的所有接口名
    4. 获取所有内部类的名字
    5. 判断是不是抽象类
    6. 判断是不是接口
    7. 判断是不是一个注解
    8. 获取拥有某个注解的方法集合
    9. 获取类上添加的所有注解信息
    10. 获取类上添加的所有注解类型集合

    值得注意的是,CachingMetadataReaderFactory解析某个.class文件得到MetadataReader对象是利用的ASM技术并没有加载这个类到JVM。并且,最终得到的ScannedGenericBeanDefinition对象,beanClass属性存储的是当前类的名字,而不是class对象。(beanClass属性的类型是Object,它即可以存储类的名字,也可以存储class对象)

    最后,上面是说的通过扫描得到BeanDefinition对象,我们还可以通过直接定义BeanDefinition,或解析spring.xml文件的,或者@Bean注解得到BeanDefinition对象。(后续会分析@Bean注解是怎么生成BeanDefinition的)。

    2. 合并BeanDefinition

    通过扫描得到所有BeanDefinition之后,就可以根据BeanDefinition创建Bean对象了,但是在Spring中支持父子BeanDefinition,和Java父子类类似,但是完全不是一回事。

    父子BeanDefinition实际用的比较少,使用是这样的,比如:

    1. "parent" class="com.zhouyu.service.Parent" scope="prototype"/>
    2. "child" class="com.zhouyu.service.Child"/><
  • 相关阅读:
    解决 pdf.js 出现 TypeError: key.split(...).at is not a function 报错问题
    OpenCV_Mat类对象常用属性值的获取方法
    python数据分析及可视化(六)Pandas的对齐运算、混合运算、统计函数、排序函数、处理缺失值及数据的存储与读取
    经验篇:大数据常用工具集合
    美创数据库安全审计DAS通过IPv6 Ready Logo认证
    JDK发布信息、历史及未来规划
    字体锯齿问题
    深入理解Java IO流(第二篇)
    Mybatis防止Sql注入
    基于Lattice的密码学
  • 原文地址:https://blog.csdn.net/weixin_43874650/article/details/134212708