SpringBoot的启动流程源码分析

这篇具有很好参考价值的文章主要介绍了SpringBoot的启动流程源码分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

new 一个IOC容器,传入配置好的文件xml,在这个地方打bug

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);

SpringBoot的启动流程源码分析,spring boot,java,spring

在这个debug的栈帧中,下面几个不用看,直接看到getBean

SpringBoot的启动流程源码分析,spring boot,java,spring

内容如图所示,name传的就是我们在xml的bean标签的id,这里是instanceA

SpringBoot的启动流程源码分析,spring boot,java,spring

进入到doGetBean后,因为我是从IOC初始化容器debug进来的所以第一次通过。

Object sharedInstance = getSingleton(beanName); //sharedInstance为null

从一级缓存获取到的值是为null,所以需要进行创建。

SpringBoot的启动流程源码分析,spring boot,java,spring

上面下来后,这里判断当前bean是否产生了循环依赖,注释意思是“如果我们已经创建失败这个bean实例:我们大概在一个循环引用”,意思就是如果产生循环依赖这里就是true,则直接抛异常。但是并没有,所以往下走。

SpringBoot的启动流程源码分析,spring boot,java,spring

这里判断是否为父子容器(父子容器能够解决在相同bean里名字重复依赖注入是导致的报错,因为父子容器之间是隔离的,但是子容器可以去访问父容器,父容器不可以访问子容器,而子容器可以通过任何方式注入父容器的bean,调用子容器的getBean方法获取bean的时候,会沿着当前容器开始向上面的容器进行查找,直到找到对应的bean为止),显然只是用了一个单例进行所以返回null,继续往下

SpringBoot的启动流程源码分析,spring boot,java,spring

进入方法

SpringBoot的启动流程源码分析,spring boot,java,spring

这行代码检查当前bean是否为抽象的,显然这个bean不是

SpringBoot的启动流程源码分析,spring boot,java,spring

当我们在xml中声明时,它才会是true,是true就会抛出异常,因为抽象类不能被实例化

SpringBoot的启动流程源码分析,spring boot,java,spring

这里的dependsOn表明当前bean是否与其他bean具有依赖关系

SpringBoot的启动流程源码分析,spring boot,java,spring

这也是在xml声明,显然这里没有,继续往下

SpringBoot的启动流程源码分析,spring boot,java,spring

这里传入一个lambda表达式进去,其中createBean就是创建bean的逻辑方法,而且这里也是返回instanceA实例的地方,所以就需要重点观察这里

SpringBoot的启动流程源码分析,spring boot,java,spring

进入方法后我们就可以发现,它去获取了concurrentHashmap里面的值,那肯定是为null的,注意这里返回的是Object类型的,所以我们只需排查出返回Object类型的方法就可以

SpringBoot的启动流程源码分析,spring boot,java,spring

先看这行代码,它会把当前beanId装入set集合中,如果此时又有一个线程来创建相同的beanId就会抛异常,进入这个方法

SpringBoot的启动流程源码分析,spring boot,java,spring

我们可以看到如果if条件成立就会抛异常

SpringBoot的启动流程源码分析,spring boot,java,spring

定位到这里,其实就是调用了前面传进来的lambda表达式的那个返回值,也就createBean()方法

SpringBoot的启动流程源码分析,spring boot,java,spring

进入createBean()方法

SpringBoot的启动流程源码分析,spring boot,java,spring

它返回是一个Object类型的对象,那就定位到了具有返回object对象的方法上,spring源码中一般以do开头的方法就是真正干活的

SpringBoot的启动流程源码分析,spring boot,java,spring

此时定位到这两个画线的方法,其返回类型都是Object

SpringBoot的启动流程源码分析,spring boot,java,spring

通过debug发现下面一个返回了bean的实例对象,这就是我们需要了解的方法,进入这个方法

SpringBoot的启动流程源码分析,spring boot,java,spring

debug在该方法继续向下

SpringBoot的启动流程源码分析,spring boot,java,spring

划线就是通过反射创建了bean对象,但是是一个空壳子,就是没有属性,里面很实现很复杂,debug继续往下

SpringBoot的启动流程源码分析,spring boot,java,spring

此时会进入addSingletonFactory()方法

SpringBoot的启动流程源码分析,spring boot,java,spring

这个方法的作用就是把我们更改获取得到的bean的早期对象(空壳对象)放入三级缓存当中(一级缓存存放的就是实例对象,二级缓存充当一个一个中介,存放的也是早期对象),三级缓存用于解决循环依赖问题

SpringBoot的启动流程源码分析,spring boot,java,spring

添加完成后继续往下

populateBean(beanName, mbd, instanceWrapper);//用于暴露上一步早期(空壳)对象

如果A依赖B,B也依赖于A,就是A中注入了B则先会去创建B的实例对象进行注入,而此时B走的流程跟A是一模一样的,等到B也执行到populateBean(beanName, mbd, instanceWrapper)时,发现需要注入A对象,此时,就又会从刚开始进行的流程走下来,但这时候就不一样了,B需要注入A时,因为前面A已经将早期对象放入了三级缓存当中,所以执行到

SpringBoot的启动流程源码分析,spring boot,java,spring

这里时getSingleton就不为null了,

SpringBoot的启动流程源码分析,spring boot,java,spring

进入getSingleton()方法就可以发现,它具体是先去一级缓存拿发现没有,然后再去二级缓存拿还是没有,有去三级缓存拿,找到了A的早期对象,此时就把三级缓存中的A的早期对象放入到二级缓存当中,最后就会直接返回A的早期对象给B,此时B拿到A的早期对象后会继续的往下执行,最后B得到最终实例化,注入进A当中,然后A也完成了实例化,这里就是使用了多级缓存解决了循环依赖的问题

补充:

SpringBoot的启动流程源码分析,spring boot,java,spring

画线方法能够保证如果A,B都为代理对象,此时能获取他们代理对象的引用,是一个后置的处理器,

SpringBoot的启动流程源码分析,spring boot,java,spring

在把A的早期对象加入三级缓存前,传了一个表达式,在B获取A的早期对象时,就会执行这个方法

SpringBoot的启动流程源码分析,spring boot,java,spring

跟踪就去,就是这个方法实现的

this.ingletonFactories.put(beanName, singletonFactory);//放入三级缓存 this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName);

就是这个方法

SpringBoot的启动流程源码分析,spring boot,java,spring

回到getSingleton()方法,调用lambda表达式的createBean()后返回了InstanceA的实例对象

SpringBoot的启动流程源码分析,spring boot,java,spring

往下的这行代码就是删除前面加入到Set集合里的BeanId

SpringBoot的启动流程源码分析,spring boot,java,spring

如果删除失败抛出异常

SpringBoot的启动流程源码分析,spring boot,java,spring

执行到这里就把instanceA的实例对象添加到一级缓存当中,共调用者调用

SpringBoot的启动流程源码分析,spring boot,java,spring

进入方法可以看到实例完成后就添加到了一级缓存当中

图:

SpringBoot的启动流程源码分析,spring boot,java,spring

SpringBoot的启动流程源码分析,spring boot,java,spring文章来源地址https://www.toymoban.com/news/detail-819647.html

到了这里,关于SpringBoot的启动流程源码分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot-Run启动流程(源码分析)—看不懂来揍我

    目录 前言 Run()方法 1、实例化SpringApplication对象 1、加载容器 2、装配初始化器 3、装配监听器  4、加载主类 2、执行Run()方法 1、设置headless 2、启用SpringApplicationListener 3、加载Banner 1、图片Banner 2、文本Banner 4、异常报告类加载 5、准备上下文         6、刷新上下文 7、系统

    2024年02月14日
    浏览(38)
  • Spring Boot 启动流程

    加载配置 Spring Boot在启动时会加载应用程序的配置文件(例如application.properties或application.yml),并将其转化为内部的配置对象。 创建应用程序上下文 Spring Boot会创建一个应用程序上下文(ApplicationContext),它是Spring框架的核心容器。应用程序上下文负责管理Bean的生命周期和

    2024年02月06日
    浏览(48)
  • Spring Boot的启动流程

    Spring Boot是作为Spring的脚手架框架,其本身并不提供Spring的核心功能,而是来达到快速构建项目、预置三方配置、开箱即用的目的 。 从本质上来说,Spring Boot就是Spring,它做了那些没有它你自己也会去做的Spring Bean配置。 Spring Boot使用“习惯优于配置”的理念让你的项目快速

    2024年02月02日
    浏览(37)
  • Spring Boot启动流程简析

    文章首发地址 可以穿件独立的Spring应用程序,可以创建可执行的jars 内嵌tomcat或jetty等Servlet容器 提供“入门”依赖项,以简化构建配置。尽可能自动配置Spring和第三方库 提供可用于生产的功能,例如指标、运行状况检查和外部化配置 了解基本的启动注解 AnnotationUtil.java,该

    2024年02月16日
    浏览(57)
  • 三分钟了解Spring Boot 的启动流程

    👏作者简介:大家好,我是冰点,从业11年,目前在物流独角兽企业从事技术方面工作, 🍂博主正在努力完成2023计划中:以梦为马,扬帆起航,2023追梦人 📝联系方式:iceicepip,加我进群,大家一起学习,一起进步👀 背景:最近有位开发同学说面试被问到Spring Boot 的启动

    2024年02月08日
    浏览(46)
  • 全网最清楚的:Spring Boot 启动流程讲解

    Spring Boot 启动流程 简介 步骤 加载配置 创建应用程序上下文 执行自动配置 启动应用程序 处理请求 源码层说明 扩展 自定义注解以及自定义注解实现中有bean,与启动流程什么有关 Bean扫描 注解处理 Spring Boot 的启动流程 充分利用了 Spring 框架的强大功能,同时又为开发者提供

    2024年02月07日
    浏览(46)
  • Spring Boot 3.x 系列【51】启动流程 | 最后阶段

    有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot版本3.1.0 源码地址:https://gitee.com/pearl-organization/study-spring-boot3 终于启动流程到了最后一个阶段,这里主要是打印启动完成日志、调用监听器、运行 Runners 等 。

    2024年02月15日
    浏览(43)
  • Spring Boot(四):Spring Boot启动原理分析

    文章目录 Spring Boot启动原理分析 一、依赖导入原理 二、Spring Boot包扫描原理 

    2024年02月01日
    浏览(47)
  • 11.spring boot 启动源码(一)

    spring boot 版本 2.6.13 spring boot 启动源码(一) 涉及 SpringApplication 中静态与实例方法 run 方法源码解析、配置文件和 Actuator

    2024年01月19日
    浏览(43)
  • 【Spring Boot 源码学习】自动装配流程源码解析(上)

    《Spring Boot 源码学习系列》 上篇博文,笔者带大家从整体上了解了AutoConfigurationImportSelector 自动装配逻辑的核心功能及流程,由于篇幅有限,更加细化的功能及流程详解还没有介绍。本篇开始将从其源码入手,重点解析细化后的自动装配流程源码。 在开始本篇的内容介绍之前

    2024年02月14日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包