SpringBoot自动配置原理

前言

只有光头才能变强。html

文本已收录至个人GitHub仓库,欢迎Star:github.com/ZhongFuChen…java

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

做为一名Java程序员,就不可能不了解SpringBoot,若是不了解(赶忙学!)程序员

1、SpringBoot的自动配置原理

不知道你们第一次搭SpringBoot环境的时候,有没有以为很是简单。无须各类的配置文件,无须各类繁杂的pom坐标,一个main方法,就能run起来了。与其余框架整合也贼方便,使用EnableXXXXX注解就能够搞起来了!github

因此今天来说讲SpringBoot是如何实现自动配置的~spring

1.1三个重要的注解

咱们能够发现,在使用main()启动SpringBoot的时候,只有一个注解@SpringBootApplicationtomcat

只有一个@SpringBootApplication注解

咱们能够点击进去@SpringBootApplication注解中看看,能够发现有三个注解是比较重要的:框架

SpringBootApplication注解详情

  • @SpringBootConfiguration:咱们点进去之后能够发现底层是Configuration注解,说白了就是支持JavaConfig的方式来进行配置(使用Configuration配置类等同于XML文件)。
  • @EnableAutoConfiguration:开启自动配置功能(后文详解)
  • @ComponentScan:这个注解,学过Spring的同窗应该对它不会陌生,就是扫描注解,默认是扫描当前类下的package。将@Controller/@Service/@Component/@Repository等注解加载到IOC容器中。

因此,Java3yApplication类能够被咱们当作是这样的:ide

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public class Java3yApplication {

    public static void main(String[] args) {
        SpringApplication.run(Java3yApplication.class, args);
    }
}
复制代码

1.2重点EnableAutoConfiguration

咱们知道SpringBoot能够帮咱们减小不少的配置,也确定听过“约定大于配置”这么一句话,那SpringBoot是怎么作的呢?其实靠的就是@EnableAutoConfiguration注解。spring-boot

简单来讲,这个注解能够帮助咱们自动载入应用程序所须要的全部默认配置

介绍有一句说:

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

若是你的类路径下有tomcat-embedded.jar包,那么你极可能就须要TomcatServletWebServerFactory

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

EnableAutoConfiguration注解详情

  • @AutoConfigurationPackage:自动配置包
  • @Import:给IOC容器导入组件

1.2.1AutoConfigurationPackage

网上将这个@AutoConfigurationPackage注解解释成自动配置包,咱们也看看@AutoConfigurationPackage里边有什么:

AutoConfigurationPackage注解实现

咱们能够发现,依靠的仍是@Import注解,再点进去查看,咱们发现重要的就是如下的代码:

@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
	register(registry, new PackageImport(metadata).getPackageName());
}

复制代码

默认的状况下就是将:主配置类(@SpringBootApplication)的所在包及其子包里边的组件扫描到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,可能会在实体类上写@Entity注解。这个@Entity注解由@AutoConfigurationPackage扫描并加载,而咱们平时开发用的@Controller/@Service/@Component/@Repository这些注解是由ComponentScan来扫描并加载的。

  • 简单理解:这两者扫描的对象是不同的。

1.2.2回到Import

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

获得不少配置信息

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

经过SpringFactoriesLoader来加载

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

跟踪实现

简单梳理:

  • FACTORIES_RESOURCE_LOCATION的值是META-INF/spring.factories
  • Spring启动的时候会扫描全部jar路径下的META-INF/spring.factories,将其文件包装成Properties对象
  • 从Properties对象获取到key值为EnableAutoConfiguration的数据,而后添加到容器里边。

从Properties对象获取到EnableAutoConfiguration.class对应的值,而后添加到容器里边

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

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

加载的配置类和文件的信息

1.3总结

@SpringBootApplication等同于下面三个注解:

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

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

自动配置功能

官网文档参考:

英语很差的同窗能够像我同样,对照着来看:

一边插件,一边原文

最后

乐于输出干货的Java技术公众号:Java3y。公众号内有200多篇原创技术文章、海量视频资源、精美脑图,不妨来关注一下!

帅的人都关注了

以为个人文章写得不错,不妨点一下

相关文章
相关标签/搜索