Link

有道链接

深度探索JFR - JFR详细介绍与生产问题定位落地 - 1. JFR说明与启动配置 - 知乎 (zhihu.com)

Bean的生命周期&循环依赖


<aside> 💡 Spring最重要的功能就是IOC,而启动Spring就是为创建Bean对象做准备, 所以我们先明白Spring到底是如何去创建Bean的, 也就是先弄明白Bean的生命周期。 Bean的生命周期流程就是: 在Spring中,Bean对象是如何创建的, 是如何销毁的。

</aside>

Untitled

<aside> 🫘 bean的创建 org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String) ****调用createBean方法不分单例bean还是原型beam

  1. 调用getSingleton方法, 传入lambda表达式(底层调用createBean方法)createBean流程:
    1. 类的加载
      1. beanClass属性一开始是String如果类被加载了, 就会变成class对象
      2. 获取类加载器, ,优先就从线程中获取线程的类加载器, Spring项目是运行在Tomcat容器中的 所以会优先获取Tomcat自定义的类加载器, 所以可以和Tomcat联系起来
      3. 类加载器为null, 获取加载ClassUtils类的类加载器
      4. 如果spring-core包放在jre/lib 目录下,获取不到ClassUtils类的类加载器 ClassUtils是被Bootstrap类加载器加载的, 则获取系统类加载器
      5. 如果不是spring表达式. 用类加载器加载这个class
    2. 实例化前 处理InstantiationAwareBeanPostProcessor
      1. 可以自定义实例化方法
    3. 创建bean AbstractAutowireCapableBeanFactory.doCreateBean
      1. 实例化bean
      2. 后置处理合并后的BeanDefinition, 可以对BD进行加工
      3. 实例化后
      4. 为了解决循环依赖提前缓存单例创建工程-添加到三级缓存
      5. 填充属性
      6. 初始化
      7. 注册bean的销毁
      8. 返回创建出来的bean
    4. 初始化后
  2. 标记为创建中(解决循环依赖)
  3. 加入到单例池

其他scope

  1. 可以实现request/session作用域缓存的功能 (request.getAttritue())
  2. 调用Scope.get()方法获取bean </aside>

Bean生成过程

1. 生成BeanDefinition

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

**https://www.processon.com/view/link/61370ee60e3e7412ecd95d43**

  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加入结果集

Spring扫描底层流程

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

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