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. 《Java项目中classpath路径详解》

    项目里用到了classpath路径来引用文件,那么classpath指的是哪里呢 我首先把上面的applicationContext.xml文件放在了src目录下发现可以. 那么classpath到底 ...

  2. 分布式存储ceph理论

    一.ceph简介 Ceph是一种具有优秀性能,可靠性和可扩展性,统一的分布式文件系统.ceph 的统一体现在可以提供文件系统.块存储和对象存储,分布式体现在可以动态扩展.在国内一些公司的云环境中,通常 ...

  3. iOS 9之后Url链接的NSUTF8StringEncoding转码实现

    在iOS中通过WebView加载Url或者请求HTTP时,若是链接中包含中文.特殊符号&%或是空格等都需要预先进行一下转码才可正常访问. 许久没编码,原先的方法已废弃了都,在此对应当前最新的方 ...

  4. Scrapy框架之CrawlSpider

    提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基 ...

  5. java自动化-关键字驱动在junit接口自动化的应用

    本文是继承上文的基础上进行的讨论,建议读者先阅读http://www.cnblogs.com/xuezhezlr/p/9097137.html和https://www.cnblogs.com/xuez ...

  6. javascript 数据类型 -- 分类

    一.概念 Javascript 中有6中基本类型(也称 原始类型/原始值): number . sring . boolean . symbol . undefined 和 null ,和1种引用类型 ...

  7. BZOJ5326 : [Jsoi2017]博弈

    将所有物品按照$b$的选择顺序排序,则先手在任意前$i$个物品中最多只能拿走$\lceil\frac{i}{2}\rceil$个物品. 将每个物品的价值设为$a+b$,那么答案为先手拿走的价值和减去所 ...

  8. On the Optimal Approach of Survivable Virtual Network Embedding in Virtualized SDN

    Introduction and related work 云数据中心对于虚拟技术是理想的创新地方. 可生存性虚拟网络映射(surviavable virtual network embedding ...

  9. 服务器http://localhost:8080要求用户输入用户名和密码

    我们在将web项目部署运行的时候,想要在浏览器上输入http://localhost:8080时却提示: 如果你的电脑安装过Oracle的话,可能是和Oracle 的端口一样了,这是可以有两个办法解决 ...

  10. mysql8.0.13修改密码

    在安装完数据库后,由于自己不小心直接关闭了安装窗口,或者长时间没有使用root用户登录系统,导致忘记了root密码,这时就需要重置MySQL的root密码.当然,最简单方式自然是删除数据库的data目 ...