记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新。欢迎大家指正!

环境: spring5.X + idea

建议:学习过程中要开着源码一步一步过

Spring中对象的创建宏观流程:

  1. 创建对象需要的基础数据:beanDefinition

在BeanFactory中getBean时做一下三步处理完成对象的创建

  1. 创建对象:AbstractAutowireCapableBeanFactory中doCreateBean
    createBeanInstance(beanName, mbd, args);
  2. 属性赋值:AbstractAutowireCapableBeanFactory中doCreateBean
    populateBean(beanName, mbd, instanceWrapper);

    这里属性赋值也就是注入分为多种方式

    a. 配置文件

    <bean autowired= "bytype|byname"/>
    <beans default-autowired="bytype|byname"/>

    b. 注解 @Autowired

  3. 对象初始化:AbstractAutowireCapableBeanFactory中doCreateBean
    initializeBean(beanName, exposedObject, mbd);

    在初始化的过程中细分了几个部分分别是

    a. aware

    b. BeanPostProcessors

    c. InitMethods

宏观流程了解清楚了之后,先分析一下createBean之前spring做了那些事,也就是Beanfactory调用doGetBean然后执行createbean调用AbstractAutowireCapableBeanFactory中的doCreateBean之前Spring还做了什么样的处理

上源码(createbean执行之前)

String beanName = this.transformedBeanName(name);
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if(sharedInstance != null && args == null) {
//日志打印的
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
}

源码说明:else 之前就是创建对象之前做的一些事情

  1. 获取bean的id值:transformedBeanName(name)

    说明:从这个方法的命名就可以知道他是用来转化对象对象名的,Spring配置Bean的时候可以写id,name,别名,这里就是把这些转换成这个对象的唯一id供后续使用。
  2. 通过当前的id获取是否有已经创建好的对象:getSingleton(beanName)

    说明:从单例池中获取对象,然后判断是否获取到对应的对象,如果没有获取到就执行else去创建,如果获取到了Spring又做了一个普通对象还是实现了FactoryBean接口的对象,getObjectForBeanInstance,如果是普通对象直接返回,如果是实现了FactoryBean接口对象就会调用getObject方法返回。

    三级缓存:单例池最根本的实现是Spring设计了一个三级缓存,也就是DefaultSingletonBeanRegistry中的三个Map

    • singletonObjects 一级缓存
    • earlySingletonObjects 二级缓存
    • singletonFactories 三级缓存
      protected Object getSingleton(String beanName, boolean allowEarlyReference) {
      Object singletonObject = this.singletonObjects.get(beanName);
      if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      synchronized (this.singletonObjects) {
      singletonObject = this.earlySingletonObjects.get(beanName);
      if (singletonObject == null && allowEarlyReference) {
      ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
      if (singletonFactory != null) {
      singletonObject = singletonFactory.getObject();
      this.earlySingletonObjects.put(beanName, singletonObject);
      this.singletonFactories.remove(beanName);
      }
      }
      }
      }
      return singletonObject;
      }
  3. 执行else分支时Spring在调用createbean方法之前还做了一些父子工厂相关的处理

    说明:如果存在父子工厂,那么他们的配置会融合,发现同名配置会优先使用子工厂中的配置
    BeanFactory parentBeanFactory = this.getParentBeanFactory();
    if(parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
    String nameToLookup = this.originalBeanName(name);
    if(parentBeanFactory instanceof AbstractBeanFactory) {
    return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
    }
    if(args != null) {
    return parentBeanFactory.getBean(nameToLookup, args);
    }
    if(requiredType != null) {
    return parentBeanFactory.getBean(nameToLookup, requiredType);
    }
    return parentBeanFactory.getBean(nameToLookup);
    }

    说明:获取父类工厂,如果存在父工厂并且子工厂中没有对应的BeanDefinition就从父工厂中递归查找,然后实例化对应的对象。如果父工厂中也没有找到当前的这个对象那就是自己创建,调用createBeandoCreateBean中执行创建对象的那几步。

最后

感谢您的阅读,有什么意见和问题欢迎评论区留言!书写不易!

觉得文章对你有帮助记得给我点个赞,欢迎大家关注和转发文章!

Spring框架源码干货分享之三级缓存和父子工厂的更多相关文章

  1. 干货分享之Spring框架源码解析01-(xml配置解析)

    记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新.欢迎大家指正! 环境: spring5.X + idea Spring 是一个工厂,是一个负责对象的创建和维护的工厂.它给我 ...

  2. 干货分享之spring框架源码分析02-(对象创建or生命周期)

    记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新.欢迎大家指正! 环境: spring5.X + idea 之前分析了Spring读取xml文件的所有信息封装成beanDef ...

  3. spring源码干货分享-对象创建详细解析(set注入和初始化)

    记录并分享一下本人学习spring源码的过程,有什么问题或者补充会持续更新.欢迎大家指正! 环境: spring5.X + idea 建议:学习过程中要开着源码一步一步过 Spring根据BeanDe ...

  4. Spring框架源码阅读之Springs-beans(一)容器的基本实现概述(待续)

    去年通过实际框架代码的阅读,以及结合<Spring源码深度解析>和<Spring技术内幕>的阅读,对Spring框架内Bean模块有了一个整体性的认识.对此进行的总结性整理和回 ...

  5. 设计模式(五)——原型模式(加Spring框架源码分析)

    原型模式 1 克隆羊问题 现在有一只羊 tom,姓名为: tom, 年龄为:1,颜色为:白色,请编写程序创建和 tom 羊 属性完全相同的 10 只羊. 2 传统方式解决克隆羊问题 1) 思路分析(图 ...

  6. spring框架源码编译

    程序猿小菜一枚,最近从github上面下载下来一份spring各个项目的源码一份,但是弄了很长时间,因为网速和(fanqiang)的速度,希望大家不要再为这种无谓的时间花费时间,简单来说github上 ...

  7. springboot mybatis 项目框架源码 shiro 集成代码生成器 ehcache缓存

    1.代码生成器: [正反双向](单表.主表.明细表.树形表,快速开发利器)freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本.处理类.service等完整模块2. ...

  8. 搞清楚Spring事件机制后:Spring的源码看起来简单多了

    本文主讲Spring的事件机制,意图说清楚: 什么是观察者模式? 自己实现事件驱动编程,对标Spring的事件机制 彻底搞懂Spring中的事件机制,从而让大家 本文内容较长,代码干货较多,建议收藏后 ...

  9. 曹工说Spring Boot源码系列开讲了(1)-- Bean Definition到底是什么,附spring思维导图分享

    写在前面的话&&About me 网上写spring的文章多如牛毛,为什么还要写呢,因为,很简单,那是人家写的:网上都鼓励你不要造轮子,为什么你还要造呢,因为,那不是你造的. 我不是要 ...

随机推荐

  1. python -三元表达式、列表生成式、字典生成式

    目录 1.三元表达式 2.列表生成式 3.字典生成式 1.三元表达式 定义格式:true_return if condition else false_return if 后条件成立返回,true_r ...

  2. Docker Compose 容器编排 NET Core 6+MySQL 8+Nginx + Redis

    环境: CentOS 8.5.2111Docker 20.10.10Docker-Compose 2.1.0 服务: db  redis  web nginx NET Core 6+MySQL 8+N ...

  3. [hdu7026]Might and Magic

    (以下默认$A_{0},D_{0},P_{0},K_{0}$都为非负整数) 显然存活轮数$S=\lceil\frac{H_{0}}{C_{p}\max(A_{1}-D_{0},1)}\rceil$​​ ...

  4. [bzoj4650]优秀的拆分

    由于字符串是AABB的形式,枚举AA和BB中间的位置,分别考虑AA和BB的数量,乘起来sigma一下即为答案以下考虑AA的情况(BB同理),枚举A的长度,然后按照这个长度分为若干块,那么每一个A一定可 ...

  5. ES6学习 第二章 变量的解构赋值

    前言 该篇笔记是第二篇 变量的解构赋值. 这一章原文链接: 变量的解构赋值 解构赋值 ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 解构 ...

  6. C/C++ Qt 自定义Dialog对话框组件应用

    在上一篇博文 <C/C++ Qt 标准Dialog对话框组件应用> 中我给大家演示了如何使用Qt中内置的标准对话框组件实现基本的数据输入功能. 但有时候我们需要一次性修改多个数据,使用默认 ...

  7. radio两行每行只能选择一个的解决方案!

    如图,我要做到这个效果,竖着每行只能有一个最像,和最不像,点击左边禁用右边 <div v-else> <div v-if="progress<quiz.length& ...

  8. C#.NET 操作Windows服务(安装、卸载)

    注意点: 1.安装时要请求到管理员权限. 2.卸载前,一定要停止掉Windows服务,否则需要重启或注销电脑.代码无法停止服务时,使用services.msc来停止. 开始: 1.新建一个名为&quo ...

  9. C语言 fastq文件转换为fasta文件2

    修改可读取压缩格式文件 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #in ...

  10. shell 小数的比较大小问题

    经过实验,if 语句中的数值判断是不可以比较小数大小的:-gt -ne 2. 直接用awk awk -v  num1=6.6 -v num2=5.5  'BEGIN{print(num1>num ...