springboot 源码_springboot源码解析「建议收藏」

springboot 源码_springboot源码解析「建议收藏」1、springboot是什么?脚手架,纵观框架的发展过程,最终由springboot出来做了SSM的整合,方便程序员偷懒,因为SSM整合过程中有很多的配置,很多的依赖,很容易出错,也不方便快速开发。2、spring创建对象的过程,图解开始springboot源码讲解1、springboot的启动过程1、解释下beanFactory和factoryBean之间的区别?二者都是用来生产对象的,但是f...

1、springboot是什么?

脚手架,纵观框架的发展过程,最终由springboot出来做了SSM的整合,方便程序员偷懒,因为SSM整合过程中有很多的配置,很多的依赖,很容易出错,也不方便快速开发。

1195ef7771dd7ee44bd55e6af653e78a.png

2、spring创建对象的过程,图解

开始springboot源码讲解

1、springboot的启动过程

3b47ab258f77ac8e04f7ccbccbdf607b.png

1、解释下beanFactory和factoryBean之间的区别?

二者都是用来生产对象的,但是factoryBean提供了三个方法,其中一个是getObject(),那已经有了beanFactory了,为什么还要有一个factoryBean?

当我们要生成一个唯一的,复杂的对象的时候就需要用factoryBean了,这时候是不需要用工厂来创建的,单独拿一个工厂出来建这一的一个对象是没有意义的。

一句话解释:beanfactory用来创建一系列有公用模板的对象,而factorybean用来创建唯一的、具有复杂对象的一些对象,比如openFeign,openFeign实现的就是factoryBean接口。

具体用哪个还是要看具体的需求

开始讲解boot源码,从启动过程说起

1、从主启动类点进去,先new springApplication对象

cab056ac7ecff90f551e9be1c9d2517c.png

这7行代码比较重要:

this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); //把主启动类放到一个hahset中,因为后面有很多地方需要用到

this.webApplicationType = WebApplicationType.deduceFromClasspath(); //设置应用程序的类型,这里应用程序的类型总的会有三种,点进去就知道了:

NONE、SERVLET、REACTIVE 一般都是基于servlet的应用程序

setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));//设置初始化器

007ba7b37d93ca4a657545e894aee3a0.png
44631bf4ab04108c27c036cf73d96346.png

可以看下这个

6f01ced690404707652d0446e6512b01.png
1995a801a4def6d710313d1d0b992229.png

总结下来就是去读取了spring.factories 配置的监听器和初始化器,初始化器一共7个,监听器11个,注意:这里这是取出了类的完全限定名(包名+类名),并不是对象,可以方便以后通过反射获取到对象。

fae06d9957f78c261f33f6bbb4269076.png

到这里就已经把全限类名实例化了,这里有一个点需要注意,如果你的项目里面也有spring.factories 文件,那项目启动的时候也会去读你的配置文件。

deduceMainApplicationClass();

//判断当前是否一个web应用

//从多个配置类中找到有main方法的主配置类,然后进行启动

46d00d3b45292906e33613dce411a7a5.png

以上就完成了springapplication对象的创建,下面开始run

00694c0282ea09a141bee9022cca7f0d.png

1、计时操作:

3ae7218f3f072c477fd42cfc26ad15fd.png

2、启动监听器,监听自己负责的事件,发布了一个事件,所有监听器判断是否自己需要处理,需要就处理自己对应的逻辑

1aa2dc6a455fb456c452fd14b4caf834.png

3、开始准备环境

2f5edb57d7d7020d77c943630fabae8a.png

3.1读取所有的环境变量

40891b2b357500fd63dbc3bb02e3c808.png

4、忽略环境属性

configureIgnoreBeanInfo(environment);

cf8e8e6c79d7205f44ffe7e0df81521c.png

5、打印banner

Banner printedBanner = printBanner(environment);

扩展:什么叫上下文?

某个作用域里面所需的一些属性,信息,叫做上下文。就是为了获取某个作用域的一些对象

6、创建上下文:首先判断需要创建什么类型的上下文

a8545337e58749d67fc26ab408a575f5.png

这里创建什么类型的上下文,我不cary,我只要知道创建完对应的上下文之后我就可以获取到对应上下文环境的属性值、也可以往上下文中设置属性和参数。

7、开始处理上下文对象

d3562044397492c3be21526ae3e77b08.png

7.1 postProcessApplicationContext获取到bean工厂,设置conversionService——还是进行参数设置的

什么叫conversionService?

类型转换服务,比如我们写了一个abc=123,他是如何帮我们转换成一个整数的,就是这个conversionService干的事。

ce508244af7c03c5ec2c233119c0454f.png

7.2 发送上下文初始化完成事件

737baa0925865ec6b783064f1a769f18.png
11c7f0b463b3c673e38ef083ae45dc3c.png

7.3 、创建DefaultListableBeanFactory bean工厂

035f56f39309eba7f11122375d7d1bd0.png

7.4 、load扫描加载@controller @component这些注解的类

这就解释了为什么注解能被扫描到,原因就是有这样的一个注解读取器去读取的!

7ed8eab47c291ed71fc55a3f923b25f4.png

至此,prepareContext就结束了,就是为了向上下文对象中设置一系列的属性

架构君码字不易,如需转载,请注明出处:https://javajgs.com/archives/210423
0

发表评论