初窥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

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

相关文章
|
10天前
|
安全 Java 开发者
如何在Spring框架中实现横切关注点的集中管理和重用?
【4月更文挑战第30天】如何在Spring框架中实现横切关注点的集中管理和重用?
17 0
|
10天前
|
安全 Java 程序员
Spring框架的核心特性是什么?
【4月更文挑战第30天】Spring 的特性
16 0
|
1天前
|
前端开发 Java 关系型数据库
Java医院绩效考核系统源码B/S架构+springboot三级公立医院绩效考核系统源码 医院综合绩效核算系统源码
作为医院用综合绩效核算系统,系统需要和his系统进行对接,按照设定周期,从his系统获取医院科室和医生、护士、其他人员工作量,对没有录入信息化系统的工作量,绩效考核系统设有手工录入功能(可以批量导入),对获取的数据系统按照设定的公式进行汇算,且设置审核机制,可以退回修正,系统功能强大,完全模拟医院实际绩效核算过程,且每步核算都可以进行调整和参数设置,能适应医院多种绩效核算方式。
18 2
|
2天前
|
运维 监控 Java
springboot基层区域HIS系统源码
医疗(医院)机构正式使用云HIS系统之前,要先进行院内基础数据的配置,主要在数据管理模块中进行,由系统管理员来操作。
7 0
|
2天前
|
前端开发 安全 Java
使用Spring框架加速Java开发
使用Spring框架加速Java开发
5 0
|
2天前
|
设计模式 数据采集 监控
Spring日志框架
Spring日志框架
6 0
|
2天前
|
前端开发 Java 应用服务中间件
Spring MVC框架概述
Spring MVC 是一个基于Java的轻量级Web框架,采用MVC设计模型实现请求驱动的松耦合应用开发。框架包括DispatcherServlet、HandlerMapping、Handler、HandlerAdapter、ViewResolver核心组件。DispatcherServlet协调这些组件处理HTTP请求和响应,Controller处理业务逻辑,Model封装数据,View负责渲染。通过注解@Controller、@RequestMapping等简化开发,支持RESTful请求。Spring MVC具有清晰的角色分配、Spring框架集成、多种视图技术支持以及异常处理等优点。
10 1
|
2天前
|
存储 前端开发 Java
Spring Boot自动装配的源码学习
【4月更文挑战第8天】Spring Boot自动装配是其核心机制之一,其设计目标是在应用程序启动时,自动配置所需的各种组件,使得应用程序的开发和部署变得更加简单和高效。下面是关于Spring Boot自动装配的源码学习知识点及实战。
12 1
|
4天前
|
传感器 人工智能 前端开发
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
智慧校园电子班牌,坐落于班级的门口,适合于各类型学校的场景应用,班级学校日常内容更新可由班级自行管理,也可由学校统一管理。让我们一起看看,电子班牌有哪些功能呢?
45 4
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
|
10天前
|
SQL Java 数据库连接
Springboot框架整合Spring JDBC操作数据
JDBC是Java数据库连接API,用于执行SQL并访问多种关系数据库。它包括一系列Java类和接口,用于建立数据库连接、创建数据库操作对象、定义SQL语句、执行操作并处理结果集。直接使用JDBC涉及七个步骤,包括加载驱动、建立连接、创建对象、定义SQL、执行操作、处理结果和关闭资源。Spring Boot的`spring-boot-starter-jdbc`简化了这些步骤,提供了一个在Spring生态中更便捷使用JDBC的封装。集成Spring JDBC需要添加相关依赖,配置数据库连接信息,并通过JdbcTemplate进行数据库操作,如插入、更新、删除和查询。