带着萌新看springboot源码
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源码的更多相关文章
- 带着萌新看springboot源码8(spring ioc源码 完)
上一节说到实例化了所有的单实例Bean,后面还有一步遍历 12.完成容器刷新(finishRefresh();) 那个和生命周期有关的后置处理器类型是LifecycleProcessor:监听器原理我 ...
- 带着萌新看springboot源码05
上一节走了一遍从浏览器发出请求到得到向页面的流程,基本的功能是已经实现了.但是现在啊,我想自定义一个拦截器(拦截器可以做用户登录验证,如果登录了,就让你通过,如果没有登录,就重定向登录页面),这里就不 ...
- 带着萌新看springboot源码8(spring ioc源码上)
emmm.....这次先不说springboot原理,先好好回顾一下以前的注解版spring原理,先把spring原理了解清晰了,再看springboot原理更容易. 要说起spring,最重要的就是 ...
- 带着萌新看springboot源码03
上一节讲到了快速新建一个springboot应用,以及springboot的自动配置类起作用的时机,并且一起看了一个自动配置类的源码. 这一节我们来粗略看看当用户在浏览器输入一个url,怎么样返回一个 ...
- 带着萌新看springboot源码12(启动原理 下)
先继续接上一篇,那个启动原理还有一点没说完. 6. afterRefresh(context, applicationArguments); 看这个名字就知道,应该就是ioc容器刷新之后的一些操作了, ...
- 带着萌新看springboot源码11(springboot启动原理 源码上)
通过前面这么多讲解,springboot原理应该也大概有个轮廓了,一些基本的配置,从客户端url到controller(配置一些要用的组件,servlet三大组件,处理器映射器,拦截器,视图解析器这些 ...
- 带着萌新看springboot源码10(springboot+JdbcTemplate+druid)
上一节把springboot和jdbcTemplate大概用法说了一下,以及大概看了一下源码,还说了加载sql文件时的原理. 这一节来看看自动注入JdbcTemplate的原理,顺便用一用Druid数 ...
- 带着萌新看springboot源码09(springboot+JdbcTemplate)
emmm.....常规开局,继续说一下废话,前面简单的说了一下spring的ioc容器创建原理(花了不少时间去看了别人的博客+查了不少资料+自己的理解),相信大家对ioc容器有了一个初步的认识了. s ...
- 带着萌新看springboot源码04
继续开头说些废话,我也不知道什么鬼,每次写着写着经常会写到其他地方去了,太容易分神了. 这次说一下springboot对于springmvc的大概整个流程,以请求动态网页为例 . 1.梳理一下spri ...
- 带着萌新看springboot源码8(spring ioc源码下)
继续接着上一节,到了第六步(温馨提醒,内容有点小多,不过看完ioc原理就差不多了) 6.注册Bean后置处理器(registerBeanPostProcessors(beanFactory)) 最后一 ...
随机推荐
- 《Java项目中classpath路径详解》
项目里用到了classpath路径来引用文件,那么classpath指的是哪里呢 我首先把上面的applicationContext.xml文件放在了src目录下发现可以. 那么classpath到底 ...
- 分布式存储ceph理论
一.ceph简介 Ceph是一种具有优秀性能,可靠性和可扩展性,统一的分布式文件系统.ceph 的统一体现在可以提供文件系统.块存储和对象存储,分布式体现在可以动态扩展.在国内一些公司的云环境中,通常 ...
- iOS 9之后Url链接的NSUTF8StringEncoding转码实现
在iOS中通过WebView加载Url或者请求HTTP时,若是链接中包含中文.特殊符号&%或是空格等都需要预先进行一下转码才可正常访问. 许久没编码,原先的方法已废弃了都,在此对应当前最新的方 ...
- Scrapy框架之CrawlSpider
提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基 ...
- java自动化-关键字驱动在junit接口自动化的应用
本文是继承上文的基础上进行的讨论,建议读者先阅读http://www.cnblogs.com/xuezhezlr/p/9097137.html和https://www.cnblogs.com/xuez ...
- javascript 数据类型 -- 分类
一.概念 Javascript 中有6中基本类型(也称 原始类型/原始值): number . sring . boolean . symbol . undefined 和 null ,和1种引用类型 ...
- BZOJ5326 : [Jsoi2017]博弈
将所有物品按照$b$的选择顺序排序,则先手在任意前$i$个物品中最多只能拿走$\lceil\frac{i}{2}\rceil$个物品. 将每个物品的价值设为$a+b$,那么答案为先手拿走的价值和减去所 ...
- On the Optimal Approach of Survivable Virtual Network Embedding in Virtualized SDN
Introduction and related work 云数据中心对于虚拟技术是理想的创新地方. 可生存性虚拟网络映射(surviavable virtual network embedding ...
- 服务器http://localhost:8080要求用户输入用户名和密码
我们在将web项目部署运行的时候,想要在浏览器上输入http://localhost:8080时却提示: 如果你的电脑安装过Oracle的话,可能是和Oracle 的端口一样了,这是可以有两个办法解决 ...
- mysql8.0.13修改密码
在安装完数据库后,由于自己不小心直接关闭了安装窗口,或者长时间没有使用root用户登录系统,导致忘记了root密码,这时就需要重置MySQL的root密码.当然,最简单方式自然是删除数据库的data目 ...