天天看点

SpringBoot自动配置原理详解

SpringBoot自动配置原理:

SpringBoot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration。

SpringBoot自动配置原理详解

@EnableAutoConfiguration的作用是利用AutoConfigurationImportSelector给容器中导入一些组件。

SpringBoot自动配置原理详解

可以查看public String[] selectImports(AnnotationMetadata annotationMetadata)方法的内容。

SpringBoot自动配置原理详解

通过protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,      AnnotationAttributes attributes)获取候选的配置,这个是扫描所有jar包类路径下"META-INF/spring.factories";

SpringBoot自动配置原理详解

然后把扫描到的这些文件包装成Properties对象。

SpringBoot自动配置原理详解

从properties中获取到EnableAutoConfiguration.class类名对应的值,然后把他们添加在容器中。

SpringBoot自动配置原理详解

整个过程就是将类路径下"META-INF/spring.factories"里面配置的所有EnableAutoConfiguration的值加入到容器中。

SpringBoot自动配置原理详解

每一个这样XXAutoConfiguration类都是容器中的一个组件都加入到容器中,用他们来做自动配置。

每一个自动配置类进行自动配置功能,以HttpEncodingAutoConfiguration为例解释自动配置原理。

SpringBoot自动配置原理详解

根据当前不同的条件判断,决定这个配置是否生效。

SpringBoot自动配置原理详解

END          

======================================================================================================================================================

 2.转自:https://zhuanlan.zhihu.com/p/55637237

SpringBoot自动配置原理

只有光头才能变强。 文本已收录至我的GitHub仓库,欢迎Star:​​https://github.com/ZhongFuCheng3y/3y​​

回顾前面Spring的文章(以学习的顺序排好):

​​Spring入门这一篇就够了​​

​​Spring【依赖注入】就是这么简单​​

​​Spring【AOP模块】就这么简单​​

​​Spring【DAO模块】知识要点​​

​​SpringMVC入门就这么简单​​

​​SpringMVC【开发Controller】详解​​

​​SpringMVC【参数绑定、数据回显、文件上传】​​

​​SpringMVC【校验器、统一处理异常、RESTful、拦截器】​​

​​SpringBoot就是这么简单​​

​​SpringData JPA就是这么简单​​

​​Spring IOC知识点一网打尽!​​

​​Spring AOP就是这么简单啦​​

​​外行人都能看懂的SpringCloud,错过了血亏!​​

作为一名Java程序员,就不可能不了解SpringBoot,如果不了解(赶紧学!)

不知道大家第一次搭SpringBoot环境的时候,有没有觉得非常简单。无须各种的配置文件,无须各种繁杂的pom坐标,一个main方法,就能run起来了。与其他框架整合也贼方便,使用​<code>​EnableXXXXX​</code>​注解就可以搞起来了!

所以今天来讲讲SpringBoot是如何实现自动配置的~

我们可以发现,在使用​<code>​main()​</code>​启动SpringBoot的时候,只有一个注解​<code>​@SpringBootApplication​</code>​

SpringBoot自动配置原理详解

我们可以点击进去​<code>​@SpringBootApplication​</code>​注解中看看,可以发现有三个注解是比较重要的:

SpringBoot自动配置原理详解

​<code>​@SpringBootConfiguration​</code>​:我们点进去以后可以发现底层是Configuration注解,说白了就是支持JavaConfig的方式来进行配置(使用Configuration配置类等同于XML文件)。

​<code>​@EnableAutoConfiguration​</code>​:开启自动配置功能(后文详解)

​<code>​@ComponentScan​</code>​:这个注解,学过Spring的同学应该对它不会陌生,就是扫描注解,默认是扫描当前类下的package。将​<code>​@Controller/@Service/@Component/@Repository​</code>​等注解加载到IOC容器中。

所以,​<code>​Java3yApplication​</code>​类可以被我们当做是这样的:

我们知道SpringBoot可以帮我们减少很多的配置,也肯定听过“约定大于配置”这么一句话,那SpringBoot是怎么做的呢?其实靠的就是​<code>​@EnableAutoConfiguration​</code>​注解。

简单来说,这个注解可以帮助我们自动载入应用程序所需要的所有默认配置。

介绍有一句说:

if you have tomcat-embedded.jar on your classpath you are likely to want a TomcatServletWebServerFactory

如果你的类路径下有​<code>​tomcat-embedded.jar​</code>​包,那么你很可能就需要TomcatServletWebServerFactory

我们点进去看一下,发现有两个比较重要的注解:

SpringBoot自动配置原理详解

​<code>​@AutoConfigurationPackage​</code>​:自动配置包

​<code>​@Import​</code>​:给IOC容器导入组件

网上将这个​<code>​@AutoConfigurationPackage​</code>​注解解释成自动配置包,我们也看看​<code>​@AutoConfigurationPackage​</code>​里边有什么:

SpringBoot自动配置原理详解

我们可以发现,依靠的还是​<code>​@Import​</code>​注解,再点进去查看,我们发现重要的就是以下的代码:

在默认的情况下就是将:主配置类(​<code>​@SpringBootApplication​</code>​)的所在包及其子包里边的组件扫描到Spring容器中。

看完这句话,会不会觉得,这不就是ComponentScan的功能吗?这俩不就重复了吗?

我开始也有这个疑问,直到我看到文档的这句话:

it will be used when scanning for code @Entity classes. It is generally recommended that you place EnableAutoConfiguration (if you're not using @SpringBootApplication) in a root package so that all sub-packages and classes can be searched.

比如说,你用了Spring Data JPA,可能会在实体类上写​<code>​@Entity​</code>​注解。这个​<code>​@Entity​</code>​注解由​<code>​@AutoConfigurationPackage​</code>​扫描并加载,而我们平时开发用的​<code>​@Controller/@Service/@Component/@Repository​</code>​这些注解是由​<code>​ComponentScan​</code>​来扫描并加载的。

简单理解:这二者扫描的对象是不一样的。

我们回到​<code>​@Import(AutoConfigurationImportSelector.class)​</code>​这句代码上,再点进去​<code>​AutoConfigurationImportSelector.class​</code>​看看具体的实现是什么:

SpringBoot自动配置原理详解

我们再进去看一下这些配置信息是从哪里来的(进去getCandidateConfigurations方法):

SpringBoot自动配置原理详解

这里包装了一层,我们看到的只是通过SpringFactoriesLoader来加载,还没看到关键信息,继续进去:

SpringBoot自动配置原理详解

简单梳理:

​<code>​FACTORIES_RESOURCE_LOCATION​</code>​的值是​<code>​META-INF/spring.factories​</code>​

Spring启动的时候会扫描所有jar路径下的​<code>​META-INF/spring.factories​</code>​,将其文件包装成Properties对象

从Properties对象获取到key值为​<code>​EnableAutoConfiguration​</code>​的数据,然后添加到容器里边。

SpringBoot自动配置原理详解

最后我们会默认加载113个默认的配置类:

SpringBoot自动配置原理详解

有兴趣的同学可以去翻一下这些文件以及配置类哦:

SpringBoot自动配置原理详解

​<code>​@SpringBootApplication​</code>​等同于下面三个注解:

​<code>​@SpringBootConfiguration​</code>​

​<code>​@EnableAutoConfiguration​</code>​

​<code>​@ComponentScan​</code>​

其中​<code>​@EnableAutoConfiguration​</code>​是关键(启用自动配置),内部实际上就去加载​<code>​META-INF/spring.factories​</code>​文件的信息,然后筛选出以​<code>​EnableAutoConfiguration​</code>​为key的数据,加载到IOC容器中,实现自动配置功能!

SpringBoot自动配置原理详解

官网文档参考:

​​https://docs.spring.io/spring-boot/docs/2.2.0.BUILD-SNAPSHOT/reference/html/using-spring-boot.html#using-boot-structuring-your-code​​