SpringBoot自动配置原理初探

SpringBoot配置原理初探

1、SpringBoot精华之处

​        springBoot最大的特点就是在spring的基础上,大规模的缩减了配置文件的数量,以往我们要手动配置n多个属性,现如今使用了boot,即使没有任何配置,代码依然跑得通,框架依然能够搭建起来。

2、配置原理一:springBoot的启动准备工作

​       既然如此,springBoot肯定是为我们配置好了绝大多数的信息,那它是什么时候配置的,在哪里配置的,怎么配置的,为什么配置了就可以管用?

SpringBoot自动配置原理初探

SpringBoot自动配置原理初探

 

 

SpringBoot自动配置原理初探

       根据图中指示,我们发现了这么多的xxxAutoConfiguration,这些就是自动配置类,springBoot就是通过获取的它们,才做到了自动配置。那么spingBoot怎么获取的?

点开springBoot的启动类,再点开它的@SpringBootApplication注解,找到如下这个注解

SpringBoot自动配置原理初探

这个注解的功能如同字面意思一样,叫做开启自动配置功能,那再点进去

SpringBoot自动配置原理初探

 

发现它导入了一样东西,叫做"选择器"类,再点进去

SpringBoot自动配置原理初探

 

找到有这样一个方法:

List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);

这是获取到所有候选的配置,放入集合,最后将集合返回

那么整理下思路:boot项目启动时,它开启了自动配置,自动配置中用到了一个选择器,选择器获取到了所有的候选配置,boot启动就载入了这些候选配置,就是这样,有了自动配置的基础。

那接下来,点进上面的方法,再看看:

SpringBoot自动配置原理初探

有个SpringFactoriesLoader.loadFactoryNames方法,毫不犹豫再点

SpringBoot自动配置原理初探

loadFactoryNames调用了loadSpringFactories方法,而在这里,它将

"META-INF/spring.factories"这个路径下的url路径全都存了起来!

这个路径就是下面这茫茫多的xxxAutoConfiguration

SpringBoot自动配置原理初探

总结1:springBoot一启动,就通过上述一系列注解和方法,找到所有的自动配置类

而现在只是找到了所有自动配置类,配置哪些类,配置的属性都是什么,值是多少,接下来springBoot还有话说

3、配置原理二:springBoot怎么选择需要的配置

这里举例说明:以一个上图中的HttpEncodingAutoConfiguration自动配置类举例

SpringBoot自动配置原理初探

 

这个HttpEncodingAutoConfiguration,我们关注上图中的几点

1:@Configuration:说明这个是配置类

2:@EnableConfigurationProperties({HttpProperties.class}):这个注解是"开启配置属性",开启谁的?开启HttpProperties.class这个类的

什么意思呢?就是说我这个HttpEncodingAutoConfiguration自动配置类,需要用HttpProperties.class这个类里的属性值来完成配置!

再往下看类里面:

SpringBoot自动配置原理初探

 

只有一个有参构造器,一个properties属性,这个properties由这个构造器注入值,也只有通过入参HttpProperties properties来赋值

那为什么一定要赋值,因为接下来要用啊,回到HttpEncodingAutoConfiguration再往下拉:

SpringBoot自动配置原理初探

看到没,properties属性里的值要拿出来放到filter里,然后filter被返回,返回到哪儿去?

看这个方法头上的@Bean,被它标记了,返回值filter是要被注入到Ioc容器中的,而只有被注入到Ioc,配置才会真的生效

那么整理下思路:自动配置类(xxxAutoConfiguration)需要有属性和值,这些东西从哪儿来的?就是从@EnableConfigurationProperties({HttpProperties.class})来,EnableConfigurationProperties绑定了HttpProperties.class,将这里的属性和值注入到xxxAutoConfiguration类,并在该类中处理后通过@Bean注入到spring的Ioc容器中,使其生效

那就有个问题,开发人员并不是每次都使用所有的配置,如果每次都全部注入,很不合适,所以就应该考虑过滤掉那些当前开发人员不需要的配置,所以接下来看看HttpEncodingAutoConfiguration的另外两个需要我们关注的注解

SpringBoot自动配置原理初探

3:@ConditionalOnClass({CharacterEncodingFilter.class})

这个注解就是判断用的,判断CharacterEncodingFilter.class这个类是否存在,如果不存在,那么刚才说的类的绑定、属性值的注入、向Ioc的注入都不会生效了。怎么算存不存在?就是看你的pom.xml文件有没有引入对应的依赖,如果没有引入,maven就没有导入包,那个对应的类也就不存在了

4:@ConditionalOnProperty( prefix = "spring.http.encoding", value = {"enabled"}, matchIfMissing = true)

这个也是判断用的,只不过是判断属性是否存在,判断什么属性?判断在哪儿是否存在?

这就该提及:springBoot默认有四个放置配置文件的地方,此处不过多展开,我们常用的是

SpringBoot自动配置原理初探

这个注解判断的就是这里是否写了属性,什么属性?

prefix = "spring.http.encoding":前缀为spring.http.encoding的属性

只不过看matchIfMissing = true,即使没有写上面的属性,boot也默认设置了要去获取默认的值

至此,boot的自动配置已经完善了,一切准备就绪,只差我们给它提供需要配置的属性和值了

刚才说了,值从@EnableConfigurationProperties({HttpProperties.class})这里来,那么进入HttpProperties.class看看去

SpringBoot自动配置原理初探

@ConfigurationProperties( prefix = "spring.http")这个注解,boot就会从配置文件中获取前缀为"spring.http"的属性值。ConfigurationProperties的意思就是"配置属性"。

到此为止,这最后的一步,也是唯一需要我们做的,也都做好了

那都能配置哪些属性呢?

SpringBoot自动配置原理初探

只要看看这个类里有什么属性就知道了,我们能配置的,都已经在类里写好了

来验证一下:

SpringBoot自动配置原理初探

总结2:springBoot找到所有的自动配置类后,当然不能全部配置,因为你不一定都用得上,所以需要判断过滤掉不用的配置。确定以后,boot就通过自己的手段去配置文件里拿我们想要配置的属性了

说了这么多,其实最终的结论也就是总结1和总结2这么几句话。