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

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

1.首先看主配置类

小编带着小白看springboot源码_第1张图片
2.打开@SpringBootApplication这个注解

  这个类除了那个注解,一个run方法,其他的就和平常我们所写的类一样,这里就暂时先介绍这个注解。@SpringBootApplication注解,见名知意,标注这是一个springboot应用嘛!br/>![](https://s1.51cto.com/images/blog/201812/13/ee332bfb84a61a66a0f9f0b6cfa811e3.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
打开@springbootConfiguration注解可以看到就是一个@Configuration注解和一些其他元注解的组合,可以看作是springboot将spring的Configuration注解进行一个包装
小编带着小白看springboot源码_第2张图片
3.最重要的是@EnableAutoConfiguration这个注解

  打开这个注解
小编带着小白看springboot源码_第3张图片
  这个@AutoConfigurationPackage注解就是扫描跟主配置类(就是有main方法的那个类)同级目录以及子目录下的包,这也是什么我上一节说的springboot其他的包必须在主配置类同级或者子目录以下的原因,放在其他地方,扫描不到嘛!

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

4.EnableAutoConfigurationImportSelector.class内部原理
小编带着小白看springboot源码_第4张图片
 这里没什么比较厉害的方法,看他的父类AutoConfigurationImportSelector里面实现了什么功能

![](https://s1.51cto.com/images/blog/201812/13/fbd16f087e09412063f7954799d19ccc.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
这里重点是那个String[] selectImports()方法,方法里面
![](https://s1.51cto.com/images/blog/201812/13/e6d865b8399f5a9a7c020e8e542e1262.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
  继续剖析这个List configurations集合里面的东西,只要把这个集合里面的东西给剖析出来了,那整个springboot应用启动原理就清楚了

5.List configurations集合

  看到这里,List configurations = this.getCandidateConfigurations(annotationMetadata, attributes),点开getCandidateConfigurations方法,
小编带着小白看springboot源码
  SpringFactoryLoader去加载一些组件的名字,看加载那些组件的名字,继续点开loadFactory方法
小编带着小白看springboot源码
小编带着小白看springboot源码_第5张图片
  终于到最后了,最终我们就是要看上图有一行 Enumeration urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories")

  看看类路径(遍历所有jar包下)"META-INF/spring.factories"这个路径下放了一些什么鬼组件就ok了,在左侧打开所有的jar包(此处,factoryClassName传进来的是EnableAutoConfiguration.class,根据这个类名才能对应目标factories文件下的键,然后取出键对应的值)
小编带着小白看springboot源码_第6张图片
打开spring.factories,可以看到很多的东西,我们找到这一个地方
小编带着小白看springboot源码_第7张图片
  上图里面这么多的xxxAutoConfiguration就是我们的这么久得出的结果,最终就是加载这么多的类的全路径,然后springboot内部就是实例化这些类并加载到容器里面,完成springboot应用启动时的自动配置

6.调试

  我们可以在这里打个断点,进行调试
小编带着小白看springboot源码
 执行到这一步时,看configurations里面有什么东西
小编带着小白看springboot源码
看,很清晰,就是刚刚在factories配置文件里面定义的那些xxxConfiguration
小编带着小白看springboot源码_第8张图片

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

  总结一下整个过程:

    springboot应用启动------>@SpringBootApplication起作用--------->@EnableAutoConfiguration--------->【@AutoConfigurationPackage:扫描主配置类同级目录以及子包】【@Import({EnableAutoConfigurationImportSelector.class}):导入一个自动配置组件】---------->EnableAutoConfigurationImportSelector extends AutoConfigurationImportSelector ------------>public String[] selectImports() {List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);}---------->List 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原理学会了,再用起来才能更得心应手