SpringBoot修行之路-4.自动配置的奥义

概述

自动配置: 是SpringBoot提供的一种通过jar包的依赖,能够自动配置应用程序。例如:引入spring-boot-start-web之后,就自动引入了SpringMVC相关的jar包,从而达到自动配置SpringMVC的效果。

@SpringBootApplication

基本只要是一个SpringBoot项目都有这样一个注解。基本作用有以下几点:

  1. 标记是一个SpringBoot项目
  2. 开启自动配置

实现代码如下:
SpringBoot修行之路-4.自动配置的奥义

  1. @Target(ElementType.Type):表示注解的适应范围,Type表示注解可以描述类,接口,注解或者枚举中。
  2. @Retention(RetentionPolicy.RUNTIME):表示注解的生命周期,RUNTIME表示运行时。
  3. @Documented:表示注解可以纪律在javadoc中。
  4. @Inherited:表示该类可以被子类继承。(注:只有在类上使用才有效,对方法,属性无效)
  5. @SpringBootConfiguration:标明该类为配置类
  6. @EnableAutoConfiguration:启动自动配置
  7. @ComponentScan:包扫描器
    我们的重点是在第5和第6个注解上,其余如果有想了解的,可以参考博客后面附录的链接地址。

@SpringBootConfiguration

实现代码如下:SpringBoot修行之路-4.自动配置的奥义

  1. @Configuration:配置类

    可以看到@SpringBootConfiguration注解的核心是继承@Configuration注解,所以功能就可想而知。能够将当前类内的一个或多个以@Bean注解标记的方法的实例放入Spring容器中,并且实例名就是方法名。

@EnableAutoConfiguration

代码如下:
SpringBoot修行之路-4.自动配置的奥义
这里面有俩个核心的注解。

  1. @AutoConfigurationPackage:主要功能为自动配置包,会获取@SpringBootApplication注解标注的类所在的包名,并对该包及其子包进行扫描,将组件添加到容器中。
  2. @Import(AutoConfigurationImportSelector.class):通过@Import手机所有符合自动配置的bean定义,加载到容器。

我们先看@AutoConfigurationPackage,具体实现如下:
SpringBoot修行之路-4.自动配置的奥义
作用:将Registrar组件类导入到容器中。
然后我们进入到组件类中去看看,Registrar的实现如下:
SpringBoot修行之路-4.自动配置的奥义
SpringBoot修行之路-4.自动配置的奥义
可以看到最后就是将一个用于存储包名的bean注册到容器中。

看完@AutoConfigurationPackage,我们看一下@Import(AutoConfigurationImportSelector.class),实现如下:
SpringBoot修行之路-4.自动配置的奥义
方法主要高速SpringBoot需要导入哪些组件。具体实现过程如下:

  1. 判断注解EnableAutoConfiguration是否开启,默认开启(等同于是否进行自动配置)
  2. 加载classpath下的META-INF/spring-autoconfigure-metedata.properties,从中获取所有支持自动配置类的条件。(文件内容规则:自动配置的类全名.条件=值)

接下来,我们看下loadMetadata方法中,实现如下:
SpringBoot修行之路-4.自动配置的奥义
实现过程如下:
3. 读取配置文件的内容生成urls枚举对象
4. 遍历urls枚举对象,转换成properties对象并加载
5. 将生成的properties对象,转换成AutoConfigurationMetadata对象,然后返回

接下来看getAutoConfigurationEntry方法,具体实现如下:
SpringBoot修行之路-4.自动配置的奥义
方法虽长,但不复杂。主要步骤如下:

  1. 判断注解是否开启
  2. 获取注解的属性 比如元数据等
  3. 获取默认支持自动配置的类名列表(查找classpath上所有jar包中的META-INF/spring-factory.properties,找出其中key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的类)
  4. 找到不希望配置的类名列表并去除(exclude excludeName 配置文件中的spring.autoconfigure.exclude属性)
  5. 根据pom文件中加入的依赖文件对剩下的候选的自动配置类进行筛选,筛选出最终符合当前项目运行环境的自动配置类(@Conditionxxxx)
  6. 实例化监听器,并触发自动配置类引入完成的事件

至此,自动配置完成。

参考:
关于java中元注解Inherited 的使用说明
Spring:@ComponentScan 使用
@Import注解-导入资源
基于 Java 的配置
SpringBoot实现自动配置原理