初窥spring boot 源码之框架初始化

简介: 从Spring boot 框架初始化深入理解框架是怎么实现的

Spring boot 启动流程

框架初始化

所谓框架初始化,可以说是new 一个  SpringApplication 对象,调用其构造方法时会进行如下步骤的操作!

实际框架初始化流程,

  1. 配置资源加载器,默认启动,资源加载器是null (可以在启动时指定类加载器)
  2. 判断primarySources(servlet项目会将启动主类传入构造方法)不能为空,接下来为SpringApplication 设置primarySources
  3. 调用推断应用所属类型,webflux or none or servlet 应用环境检测 *具体方法在后面有详细写*
  4. 设置系统初始化器-》通过SpringFactoriesLoader 获取ApplicationContextInitializer 相关实现类,主要是扫描jar包下META-INF目录下的spring.factories 文件中的对应类配置
  5. 设置应用监听器-》也是通过SpringFactoriesLoader 获取ApplicationListener 相关实现类,
  6. 配置mainApplicationClass属性,也就是设置main方法所在类

探寻如上流程时,遇到一些有意思的方法

1.SpingApplication 下的 getClassLoader 方法 还会关联到 ClassUtils 中的 getDefaultClassLoader 方法,该方法应该是与双亲委派的代码很是类似。由此看出,我能看出什么呢。这个getDefaultClassLoader 方法呢,就有意思了,如果当前线程有这么一个加载器的话,就用当前线程的,没有则找到ClassUtils类的加载器,如果还是null,那么就使用systemclassloader

2.再一个就是,Throwable 类中会记录一个StackTraceElement,该元素会记录一些内容,比如当前方法所属的类名称。方法名字。。。

这个是在设置main 方法类的时候发现的。

现在深入的研究一波,getSpringFactoriesInstances 方法解析 第4步

1.先获取类加载器

2.通过SpringFactoriesLoader 的loadFactoryNames方法获 调用loadSpringFactories方法 到了set里面,保证名字的唯一

3.createSpringFactoriesInstances 方法进行对象的实例化,先通过ClassUtils.forName 获取到Class对象,再校验是否为需求的子类,通过Class对象及入参创建对应的构造方法对象,通过BeanUtils.instantiatieClass方法创建对象,并把对象放到集合中,返回对象集合。

4.对这些对象,进行一次排序根据其自定义实现的排序逻辑,或者排序器进行排序 很多都是通过order值。

loadSpringFactories流程

  1. 查缓存中是否包含对应数据,如果有直接返回,没有进行下一步
  2. 读取到META-INF目录下的spring.factories 文件
  3. 构造properties 对象所有的kv数据,通过遍历将这些接口及实现的名字拿到,
  4. 之后基于定义的接口名字为key,具体实现为value(value被声明为一个list)(接口的多个实现用“,”分割,有方法进行分割)包装到一个map中,基于这个map 取到type的具体实现类名的集合,将得到的数据放到缓存中
  5. 返回结果

框架启动

框架启动也就是在得到一个springApplication对象以后,进行的run方法的执行。执行会携带启动命令!

探秘框架启动流程

  1. 计时器开始-》new stopwatch().start()
  2. Headless 模式赋值
  3. 获取SpringApplicationRunListeners  spring-boot 框架的sping-factorise 配置文件下指定了默认的启动监听器 并发送一个ApplicationStartingEvent -》 这是个扩展点
  4. 将启动参数包装成一个对象 也就是命令行启动时的参数会通过这一步配置到 applicationArguments 对象中
  5. 配置环境数据,这个方法是配置引入的入口后面进行展开。发送一个 ApplicationEnvironmentPreparedEvent标识环境信息已经准备好了处理忽略的相关内容 -》这也是个有意思的地方
  6. 根据已经加载了配置信息的environment对象创建打印banner对象
  7. 创建应用上下文对象
  8. 创建失败分析器
  9. prepareContext 准备上下文对象 下面有详解
  10. refreshContext(context); 对上下文进行刷新,bean的初始化都在这个方法中,后面会拓展。下一个方法在默认启动中没有具体实现代码逻辑,可能是为了实现设置的。
  11. 停止计时-》 打印启动哪个类 用了多长时间 的日志
  12. 发送started事件
  13. 调用runners方法 对启动加载器进行处理
  14. 如果以上从第4步到12步有异常或者错误发生,就会通过失败分析器,发出相关失败信息。
  15. 没啥事儿再发个框架正常启动的事件,然后将上下文对象

image.png

以上为框架初始化及启动相关流程,大家加油。

相关文章
|
13天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
43 2
|
29天前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
20天前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
19天前
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
42 9
|
26天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
44 2
|
25天前
|
消息中间件 NoSQL Java
springboot整合常用中间件框架案例
该项目是Spring Boot集成整合案例,涵盖多种中间件的使用示例,每个案例项目使用最小依赖,便于直接应用到自己的项目中。包括MyBatis、Redis、MongoDB、MQ、ES等的整合示例。
81 1
|
28天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
7月前
|
Java 关系型数据库 数据库连接
Spring源码解析--深入Spring事务原理
本文将带领大家领略Spring事务的风采,Spring事务是我们在日常开发中经常会遇到的,也是各种大小面试中的高频题,希望通过本文,能让大家对Spring事务有个深入的了解,无论开发还是面试,都不会让Spring事务成为拦路虎。
97 1
|
2月前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
115 5
|
2月前
|
XML Java 数据格式
Spring底层架构源码解析(二)
Spring底层架构源码解析(二)