前言
一些朋友问我怎么读源码,这篇文章结合我看源码时候一些思路给大家聊聊,我主要从这三个方向出发:
- 确定目标,这个目标要是一个具体,不要一上来我要看懂Spring,这是不可能的,目标要这么来定,比如看懂Spring Boot的自动装配、Spring IOC XML加载流程等等,尽量小,能够快速搞定的,不要目标太大,陷入其中,反而效果不好;
- 学会猜,这个猜字其实很有精华,这个可能需要大家积累一段时间才能猜的很准,高手其实都是用猜的,我还没有达到这个境界,但是也是稍微有了一些门道,这个第二点看能力可适当应用;
- 学会看堆栈信息,这个其实很重要,刚开始看源码的时候可能是很重要的手段,一下基本上就可以看到很多很多步骤,到时候可以进行反推理;
接下来给大家演示一下,我是怎么来看Spring Boot自动装配的,希望大家能有些收获!
确定目标
看Spring Boot的自动装配流程,这个目标是个具体目标,为什么说他是一个具体目标,这里我们来思考一下,在Spring时代我们都是用配置文件来搞定的,到了Spring Boot时代我们就可以摆脱了配置,我们的目标就是看明白Spring Boot都是帮助我们做了什么,这里我们在把这个目标更具体一点,我们看一下Redis是怎么被Spring Boot自动装配的。首先我们先把Redis和Spring Boot整合起来,看一下整合过程。
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/09a161ea6e8119bf4a07aa2ee86be594.png)
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/1be26cba34efdd5c9a68300c90f64436.png)
猜
上面我们确定了目标并且完成整合,我们在程序中唯一看到就是@SpringBootApplication这个注解,那我们就跟着注解看下去,这里就开始猜的精华了。
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/612aea293cf92391e34753c945d450bc.png)
重点部分就是红色标注的部分,接下来我们继续往下看,
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/a100f9874806e2a4287bbeded209a901.png)
这个@Import注解也是最重要的部分,我们接下来继续往下看,
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/19ae741f68c7e6ec96397e9b7e21e735.png)
在AutoConfigurationImportSelector这个类中有getAutoConfigurationEntry这个方法,看这个方法的英文解释是,大致上是基于@Configuration注解返回自定义的实体AutoConfigurationEntry,感觉好像我们猜对了,看见我标注断点的地方getCandidateConfigurations这个方法,接下来我们继续往下走一走;
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/ce40d7ee167acafe955d1648ac46a7c4.png)
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/76a7776b6c19c8dc17d6ba7120da96d3.png)
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/910761bc29076c874d381e60b28365d2.png)
我们看到是加载一个配置文件地址,接下来我们去看一下配置文件中有什么东西,
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/7ca856002c0abfe66eb6f3c442d0f5f0.png)
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/fbaae4d6e3414d3ebed7cc029f626f73.png)
在这个配置文件中我们看到了RedisAutoConfiguration,看到这里我推测可能我猜的比较正确,我们看下整个类;
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/aadf1919fff0722fdb10abdca9a949a2.png)
主要看标红的地方,@EnableConfigurationProperties这个注解是导入配置注解,@Import这个注解是连接池配置信息,@Bean是Bean配置信息的导入,到这个地方我们基本上我们已经完成自己的猜测,接下来我们就进行验证;
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/7429ffa4b1c2b5b4bde038253073756b.png)
如上图,我们猜测和验证已经吻合,这个时候我们已经可以得出Spring Boot自动加载原理,总结一下:
@SpringBootApplication等同于下面三个注解:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
其中@EnableAutoConfiguration是关键(启用自动配置),内部实际上就去加载META-INF/spring.factories文件的信息,然后筛选出以EnableAutoConfiguration为key的数据,加载到IOC容器中,实现自动配置功能。
学会看堆栈信息
验证完成以后我们再来深挖一下底层一些东西,我们来看下调用的堆栈信息;
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/248b9e569513669fc4786c5b0a79b740.png)
红色标注地方,我们看到一个相对比较熟悉的方法refresh,然后继续看堆栈信息通过调用invokeBeanFactoryPostProcessors方法,通过看注释该处是执行BeanFactoryPostProcessor接口,有文章介绍过BeanFactoryPostProcessor这个接口,
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/3ab0604772acb3671196b7d877b73222.png)
大家可以去 查看一下这篇文章,这里就不进行介绍了,我们继续看堆栈信息,
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/477a405a663811e7a04a9a5a66a3ae55.png)
接下来我们看到ConfigurationClassPostProcessor类中的processConfigBeanDefinitions方法,该类继承结构如下
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/f126ae699a6e43a200d6635b4a781390.png)
断定该类主要就是向容器中注入Bean信息,继续向下看堆栈信息,发现通过调用该parse方法,最终解析在ConfigurationClassParser类中完成,
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/9d247bd495359bf671d0c79e08550a5c.png)
完成各种配置解析,我们重点关注下deferredImportSelectorHandler的process方法,
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/0d299a1f14bdfe915530f92aefd2961b.png)
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/dd4d619d556e0168693431139c2c94be.png)
processGroupImports方法通过遍历DeferredImportSelectorGrouping,该类是个静态的匿名类,内部实现迭代方法,
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/cd88c22f4876bf105f8f0735c8f195a0.png)
接下来看AutoConfigurationImportSelector的process方法,
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/256ac29723470c935d76d3099d57ea37.png)
这里重点就来了,这里就将开始断点的调用链串连起来了,相信大家看到这里已然无惑。
结束
欢迎大家加群438836709!欢迎大家关注我!
![www.wityx.com](https://i-blog.csdnimg.cn/blog_migrate/58b8af8b8f1bcab5a09bf5b0aa18abc9.png)