springboot的功能确实强悍,只需要很少的配置,就能够做出来一个简单的web应用,下面我就简要的分析一下为什么springboot能够起作用。

  不觉得很奇怪吗?只需要一个主配置类(就是启动那个main方法),就能够启动一系列的springboot功能。

1.首先看主配置类

2.打开@SpringBootApplication这个注解

  这个类除了那个注解,一个run方法,其他的就和平常我们所写的类一样,这里就暂时先介绍这个注解。@SpringBootApplication注解,见名知意,标注这是一个springboot应用嘛!

打开@springbootConfiguration注解可以看到就是一个@Configuration注解和一些其他元注解的组合,可以看作是springboot将spring的Configuration注解进行一个包装

3.最重要的是@EnableAutoConfiguration这个注解

  打开这个注解

  这个@AutoConfigurationPackage注解就是扫描跟主配置类(就是有main方法的那个类)同级目录以及子目录下的包,这也是什么我上一节说的springboot其他的包必须在主配置类同级或者子目录以下的原因,放在其他地方,扫描不到嘛!

  这里最关键的就是@Import注解向容器里导入了什么组件,导入的EnableAutoConfigurationImportSelector.class,打开这个类

4.EnableAutoConfigurationImportSelector.class内部原理

  

  这里没什么比较厉害的方法,看他的父类AutoConfigurationImportSelector里面实现了什么功能

  这里重点是那个String[] selectImports()方法,方法里面

  继续剖析这个List<String> configurations集合里面的东西,只要把这个集合里面的东西给剖析出来了,那整个springboot应用启动原理就清楚了

5.List<String> configurations集合

  看到这里,List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes),点开getCandidateConfigurations方法,

  SpringFactoryLoader去加载一些组件的名字,看加载那些组件的名字,继续点开loadFactory方法

  终于到最后了,最终我们就是要看上图有一行 Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories")

  看看类路径(遍历所有jar包下)"META-INF/spring.factories"这个路径下放了一些什么鬼组件就ok了,在左侧打开所有的jar包(此处,factoryClassName传进来的是EnableAutoConfiguration.class,根据这个类名才能对应目标factories文件下的键,然后取出键对应的值)

  

  打开spring.factories,可以看到很多的东西,我们找到这一个地方

  上图里面这么多的xxxAutoConfiguration就是我们的这么久得出的结果,最终就是加载这么多的类的全路径,然后springboot内部就是实例化这些类并加载到容器里面,完成springboot应用启动时的自动配置

6.调试

  我们可以在这里打个断点,进行调试

  执行到这一步时,看configurations里面有什么东西

看,很清晰,就是刚刚在factories配置文件里面定义的那些xxxConfiguration

   到此为止,我们就粗略的从头到尾走了一遍springboot的原理。

  总结一下整个过程:

    springboot应用启动------>@SpringBootApplication起作用--------->@EnableAutoConfiguration--------->【@AutoConfigurationPackage:扫描主配置类同级目录以及子包】【@Import({EnableAutoConfigurationImportSelector.class}):导入一个自动配置组件】---------->EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector ------------>public String[] selectImports() {List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);}---------->List<String> configurations = SpringFactoriesLoader.loadFactoryNames()---------->classLoader.getResources("META-INF/spring.factories")--------------->spring-boot-autoconfigure\1.5.9.RELEASE\spring-boot-autoconfigure-1.5.9.RELEASE.jar!\META-INF\spring.factories--------->factories里面的各种xxxxAutoConfiguration的全类名

  自己多走几遍就会了,熟能生巧,等把springboot原理学会了,再用起来才能更得心应手

带着萌新看springboot源码的更多相关文章

  1. 带着萌新看springboot源码8(spring ioc源码 完)

    上一节说到实例化了所有的单实例Bean,后面还有一步遍历 12.完成容器刷新(finishRefresh();) 那个和生命周期有关的后置处理器类型是LifecycleProcessor:监听器原理我 ...

  2. 带着萌新看springboot源码05

    上一节走了一遍从浏览器发出请求到得到向页面的流程,基本的功能是已经实现了.但是现在啊,我想自定义一个拦截器(拦截器可以做用户登录验证,如果登录了,就让你通过,如果没有登录,就重定向登录页面),这里就不 ...

  3. 带着萌新看springboot源码8(spring ioc源码上)

    emmm.....这次先不说springboot原理,先好好回顾一下以前的注解版spring原理,先把spring原理了解清晰了,再看springboot原理更容易. 要说起spring,最重要的就是 ...

  4. 带着萌新看springboot源码03

    上一节讲到了快速新建一个springboot应用,以及springboot的自动配置类起作用的时机,并且一起看了一个自动配置类的源码. 这一节我们来粗略看看当用户在浏览器输入一个url,怎么样返回一个 ...

  5. 带着萌新看springboot源码12(启动原理 下)

    先继续接上一篇,那个启动原理还有一点没说完. 6. afterRefresh(context, applicationArguments); 看这个名字就知道,应该就是ioc容器刷新之后的一些操作了, ...

  6. 带着萌新看springboot源码11(springboot启动原理 源码上)

    通过前面这么多讲解,springboot原理应该也大概有个轮廓了,一些基本的配置,从客户端url到controller(配置一些要用的组件,servlet三大组件,处理器映射器,拦截器,视图解析器这些 ...

  7. 带着萌新看springboot源码10(springboot+JdbcTemplate+druid)

    上一节把springboot和jdbcTemplate大概用法说了一下,以及大概看了一下源码,还说了加载sql文件时的原理. 这一节来看看自动注入JdbcTemplate的原理,顺便用一用Druid数 ...

  8. 带着萌新看springboot源码09(springboot+JdbcTemplate)

    emmm.....常规开局,继续说一下废话,前面简单的说了一下spring的ioc容器创建原理(花了不少时间去看了别人的博客+查了不少资料+自己的理解),相信大家对ioc容器有了一个初步的认识了. s ...

  9. 带着萌新看springboot源码04

    继续开头说些废话,我也不知道什么鬼,每次写着写着经常会写到其他地方去了,太容易分神了. 这次说一下springboot对于springmvc的大概整个流程,以请求动态网页为例 . 1.梳理一下spri ...

  10. 带着萌新看springboot源码8(spring ioc源码下)

    继续接着上一节,到了第六步(温馨提醒,内容有点小多,不过看完ioc原理就差不多了) 6.注册Bean后置处理器(registerBeanPostProcessors(beanFactory)) 最后一 ...

随机推荐

  1. vue笔记-列表渲染

    用v-for把一个数组对应为一组元素 使用方法:v-for="(item,index) in items"//也可以使用of替代in { items:源数组 item:数组元素迭代 ...

  2. linux中sogou输入法崩溃重启

    经常在linux中搜狗输入法用着用着就崩溃了,无法输入中文,又不想重启电脑,照着下面在终端输入命令可以重启输入法: 1.先关闭fcitx(小企鹅输入法,提供了良好的中文输入法环境) # killall ...

  3. Spark环境搭建(六)-----------sprk源码编译

    想要搭建自己的Hadoop和spark集群,尤其是在生产环境中,下载官网提供的安装包远远不够的,必须要自己源码编译spark才行. 环境准备: 1,Maven环境搭建,版本Apache Maven 3 ...

  4. Android四大组件的简介

    Android开发四大组件分别是: 一.活动(Activity): 用于表现功能.二.服务(Service): 后台运行服务,不提供界面呈现. 三.广播接收器(BroadcastReceiver):用 ...

  5. ionic基于GPS定位并通过百度地图获取定位详细信息

    相信所有的前端攻城狮都会碰到移动端App.里面获取用户定位信息. 那么问题来了,怎么获取用户的定位信息(经纬度)呢. 当然方法有很多,通过百度地图API 以及 高德地图 API都是可以的.但是两个获取 ...

  6. vue 时间戳 转 日期

    <text style="padding-right: 10px; color: #333; font-size: 28px" slot="value"& ...

  7. diy 滚动条 样式 ---- 核心代码

    参考自 : https://blog.csdn.net/qq_38881495/article/details/83689721 .chapter_data position relative wid ...

  8. dedecms给图片加水印覆盖整张图片

    位置: /include/image.class.php $wmwidth = $imagewidth - $logowidth; $wmheight = $imageheight - $logohe ...

  9. 了解vue APi

    阳光那么好,何必自寻烦恼,过好每一个当下,一万个美丽的未来抵不过一个温暖的现在. 一.Vue.nextTick(): 该api 是在Dom节点更新结束之后执行的一个延时回调.在修改数据之后,立即使用这 ...

  10. JAVA---MYSQL 基本知识点 第二部分

    增删改查 (CRUD):   数据库  , 表  , 记录  ;   约束 ; 主键约束 :primary key  如果是int类型 可以使用 自动增长型  auto_increment; 唯一约束 ...