Spring Boot深度实践之自动装配( 五 )


Spring Boot深度实践之自动装配
本文插图
分析源码我们看到 , @EnableAutoConfiguration被@Import标注 , 引入AutoConfigurationImportSelector类 , 此处就是用到了Spring的Enable模块装配 , AutoConfigurationImportSelector类实现了ImportSelector接口 , 在Enable模块装配方式中我们提到通过实现ImportSelector接口的selectImports抽象方法来选择要注入Spring容器的配置类 。 在AutoConfigurationImportSelector类中 , 可以发现存在这样一个方法会被selectImports方法调用 , 该方法如下图:
Spring Boot深度实践之自动装配
本文插图
可以看到方法内部调用了SpringFactoriesLoader的loadFactories方法 。 贴上loadFactories源码:
Spring Boot深度实践之自动装配
本文插图
该方法会加载所有以factoryClass为key的实现类 , 它会调用loadFactoryNames方法 , 而loadFactoryNames方法又会调用loadSpringFactories方法 , 从spring.factories文件中获取到所有实现类的全路径名 。 下图为loadSpringFactories方法源码:
Spring Boot深度实践之自动装配
本文插图
下图为spring.factories文件源码:
Spring Boot深度实践之自动装配
本文插图
那么到这里 , Spring Boot已经实例化了上图的EnableAutoConfiguration的配置实现类集合 , 我们以WebMvcAutoConfiguration为例 , 看看其内部做了什么 , 贴上源码:
Spring Boot深度实践之自动装配
本文插图
发现其被@Configuration以及@ConditionalXXX标注 , 而@Configuration是Spring 模式注解中的一种 , @ConditionalXXX则是Spring 条件装配 。
所以从整个SpringBoot自动装配的流程来看 , @EnableAutoConfiguration用于激活自动装配 , 它通过@Import注解加载EnableAutoConfiguration的实现配置类集合进Spring容器 , 而大量的EnableAutoConfiguration的实现配置类被注入Spring容器就意味着 , Spring Framework的许多功能模块会被装配到Spring工程中 , 最终我们发现 , 只需要在启动类上标注@EnableAutoConfiguration , Spring的功能模块就会自动被装配进工厂 , 这就是SpringBoot的自动装配 。
接下来 , 我们来看一个自定义实现Spring Boot自动装配的例子 。
【Spring Boot深度实践之自动装配】3.Spring Boot自动装配实践
整个过程分为三步:

  1. 激活自动装配:@EnableAutoConfiguration
  2. 实现自动装配:XXXAutoConfiguration
  3. 配置自动装配实现:META-INF/spring.factories
具体步骤
新建一个SpringBoot项目 。
自定义@Enable模块注解
1.在项目下新建一个配置类TestConfiguration , 源码如下:
package com.example.demo;?import org.springframework.context.annotation.Bean;?public class TestConfiguration {?@Beanpublic String test(){//方法名即Bean名称return ''test'';}}2.新建文件TestImportSelector,代码如下:
package com.example.demo;?import org.springframework.context.annotation.ImportSelector;import org.springframework.core.type.AnnotationMetadata;?public class TestImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{TestConfiguration.class.getName()};}}此文件中实现ImportSelector接口的selectImports方法 , 返回TestConfiguration名称 。


推荐阅读