beans context 无法解析文件_一线大牛带你深入解析AutoConfiguration源码

AutoConfiguration lmportSelector源码解析

@EnableAutoConfiguration 的关键功能是通过@Import 注解导入的 ImportSelector 来完成的从 源 代码得知@lmport(AutoConfigurationlmportSelector.class) 是@EnableAutoConfiguration 注 解 的 组成部分 , 也是自动配置功能的核心实现者 。

@Ilmport(AutoConfigurationlmportSele-ctor.class)又可以分为两部分:

@Ilmport 和对应的 ImportSelector。

本节重点讲解@lmport 的基本使用方法和ImportSelector 的实现类 AutoConfigurationlmportSelector。

@Import 注解

@lmport 注解位于 spring-context 项目内,主要提供导入配置类的功能。

为什么要专门讲解@lmport 的功能及使用呢?如果查看 Spring Boot 的源代码,我们会发现大量的 EnableXXX 类都使用了该注解。了 解@lmport 注解的基本使用方法,能够帮助我们更好地进行源代码的阅读和理解。

@lmport 的源码如下。

@Target(ElementType.TYPE)@Retention(RetentionPolicy. RUNTIME)@Documentedpublic @interface Import {Class>[] value();}

@lmport 的作用和 xml 配置中标签的作用一样,我们可以通过@lmport 弓|入@Configuration 注 解 的 类 , 也 可 以 导 入 实 现 了 ImportSelector 或ImportBeanDefinitionRegistrar 的类,还可以通过@lmport 导入普通的 POJO(将其注册成Spring Bean,导入 POJO 需要 Spring 4.2 以上版本)。

关于@lmport 导入@Configuration 注解类和 POJO 的功能比较简单和常见,就不再展开介绍了。下面重点介绍 ImportSelector 接口的作用。

ImportSelector 接口

@Import 的许多功能都需要借助接口 ImportSelector 来实现,ImportSelector 决定可引入哪些@Configuration。ImportSelector 接口源码如下。

public interface ImportSelectorString[] selectImports (AnnotationMetadata importingClassMetadata);}

ImportSelector 接口只提供了一个 参数为 AnnotationMetadata 的方法,返回的结果为一个字符串数组。其中参数 AnnotationMetadata 内包含了被@lmport 注解的类的注解信息。在selectlmports 方法内可根据具体实现决定返回哪些配置类的全限定名,将结果以字符串数组的形式返回。

如果实现了接口 ImportSelector 的类的同时又实现了以下 4 个 Aware 接口,那么 Spring 保证 在 调 用 ImportSelector 之 前 会 先 调 用 Aware 接 口 的 方 法 。 这 4 个 接 口 为 :

EnvironmentAware 、 BeanFactoryAware 、 BeanClassLoaderAware 和 ResourceLoaderAware.

在 AutoConfigurationlmportSelector 的源代码中就实现了这 4 个接口,部分源代码及 Aware的全限定名代码如下。

import org. springframework. beans. factory . BeanClassLoaderAware;import org. springframework . beans . factory . BeanFactoryAware;import org. springframework. context. EnvironmentAware;import org. springframework. context. ResourceLoaderAware;import org. springframework. context . annotation.DeferredImportSelector;import org. springframework . core . Ordered;public class AutoConfigurat ionImportSelectorimplements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware,BeanF actoryAware, EnvironmentAware, Ordered{。。。}

在.上面的源代码中,AutoConfigurationlmportSelector 并没有 直接实现 ImportSelector 接口,而是实现了它的子接口 DeferredIlmportSelector。

DeferredlmportSelector 接口与 ImportSelector 的区别是,前者会在所有的@Configuration类加载完成之后再加载返回的配置类,而 ImportSelector 是在加载完@Configuration 类之前先去加载返回的配置类。

DeferredlmportSelector 的加载顺序可以通过@Order 注解或实现 Ordered 接口来指定。同时,DeferredlmportSelector 提供了新的方法 getlmportGroup()来跨 DeferredlmportSelector实现自定义 Configuration 的加载顺序。

AutoConfigurationlmportSelector 功能概述

下面我们通过图 2-3 所示的流程图来从整体上了解 AutoConfigurationlmportSelector 的核心功能及流程,然后再对照代码看具体的功能实现。图 2-3 中省略了外部通过@Import 注解调用该类的部分。

7f54ddfa5a6c0003d3dec9a96ae72093.png

当 AutoConfigurationlmportSelector 被@lmport 注解引入之后,它的 slectmports 方法会被调用并执行其实现的自动装配逻辑。读者朋友需注意,seletmports 方法几乎涵盖了组件自动装配的所有处理逻辑。

AhtonfiruriomoprSelelereleltiports 方法源代码如下:

@Overridepublic String[ ] selectImports (AnnotationMetadata annotationMetadata) {//检查自动配置功能是否开肩,默认为开启if (!isEnabled(annotat ionMetadata)) {return NO_ IMPORTS;//加戴自动配置的元信息,配置文件为类路径中 META-INF 目录下的// spring-autoconfigure -metadata. properties 文件AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader. loadMetadata(this . beanClassLoader);//封装将被引入的自动配置信息AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntryautoConfigurationMetadata, annotationMetadata) ;//返回符合条件的配置类的全限定名数组return StringUtils. toStringArray(autoConfigurationEntry. getConfigurations());}protected AutoConfigurationEntry getAutoConfigurat ionEntry(AutoConfigurat ionMetadata autoConfi gurationMetadata,Annotat ionMetadata annotationMetadata) {if (!isEnabled( annotationMetadata)) {return EMPTY_ ENTRY;}AnnotationAttributes attributes = getAttributes ( annotat ionMetadata);//通过 SpringFactoriesLoader 类提供的方法加戴类路径中 META-INF 目录下的// spring . factories 文件中针对 EnableAutoConfigurat ion 的往册配置类List configurations = getCandidateConfigurations (annotationMetadata,attributes);//对获得的注册配置类集合进行去重处理,防止多个项目引入同样的配置类 configurations =removeDuplicates( configurations);//获得炷解中被 excLude.或 excLudeName 所排除的类的集合Set exclusions = getExclusions ( annotationMetadata, attributes);//检查被排除类是否可实例化,是否被自动注册配置所使用,不符合条件则抛出异常checkExcludedClasses (configurations, exclusions);//从自动配置类集合中去除被排除的类configurations . removeAll(exclusions);//检查配置类的注解是否符合 spring . factories 文件中 AutoConfigurat ionImportFilter.指定的注解检查条件configurations = filter( configurations, autoConfigurationMetadata);//将筛选完成的配置类和排查的配置类构建为事件类, 并传入监听器。监听器的配置在Fspring . factories 文件中,通过 AutoConf igurat ionImportL istener 指定fireAutoConfigurationImportEvents( configurations, exclusions);return new AutoConfigurat ionEntry(configurations, exclusions);}

通过图 2-3 和上述代码,我们从整体层面了解了 AutoConfigurationlmportSelector 的概况及操作流程,后文将对这些流程进行细化拆分,并通过阅读源代码来分析 Sprng Boot 是如何实现自动加载功能的。

@Enable AutoConfiguration 自动配置开关

检查自动配置是否开启的代码位于AutoConfiguratinmportSelector的selectmpots方法第一段中。 如果开启自动配置功能,就继续执行后续操作;如果未开启,就返回空数组。代码如下。

@Overridepublic String[]selectImports (AnnotationMetadata annotationMetadata) {if (!isEnabled(annotat ionMetadata)) {return NO_ IMPORTS;}}该方法主要使用 isEnabled 方法来判断自动配置是否开启,代码如下。protected boolean isEnabled(AnnotationMetadata metadata) {if (getClass() == AutoConfigurationImportSelector . class) {return getEnvironment(). getProperty(EnableAutoConfiguration. ENABLED_ _OVERRIDE_ PROPERTY, Boolean.class,true);}return true;}

通过 isEnabled 方法可以看出,如果当前类为 AutoConfigurationlmportSelector 程序会从环境中获取 key 为 EnableAutoConfiguration.ENABL ED_ OVERRIDE PROPERTY 的配置,该常量的值为 spring.boot.enableautoconfiguration.如果获取不到该属性的配置,isEnabled默认为 true,也就是默认会使用自动配置。如果当前类为其他类,直接返回 true。

如果想覆盖或重置.ENABLED_ _OVERRIDE_ PROPERTY 的配置,可获取该常量的值,并在 aplication.properties 或 plcatin.ym|中针对此参数进行配置。以 application.properties配置关闭自动配置为例,代码如下。

spring.boot.enableautoconfiguration-false

本文给大家讲解的内容是AutoConfigurationlmportSelector功能概述和AutoConfiguration自动配置开关

  1. 下篇文章给大家讲解的是AutoConfiguration加载元数据配置和加载自动配置组件;
  2. 觉得文章不错的朋友可以转发此文关注小编;
  3. 感谢大家的支持!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值