您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

一线大牛带你深入解析AutoConfiguration源码

时间:2020-10-12 09:30:02  来源:  作者:

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)
@Documented
public @interface Import {
Class<?>[] value();}

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

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

ImportSelector 接口

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

public interface ImportSelector
String[] 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 ionImportSelector
implements 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 注解调用该类的部分。

一线大牛带你深入解析AutoConfiguration源码

 

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

AhtonfiruriomoprSelelereleltiports 方法源代码如下:

@Override
public String[ ] selectImports (AnnotationMetadata annotationMetadata) {//检查自动配置功能是否开肩,默认为开启
if (!isEnabled(annotat ionMetadata)) {
return NO_ IMPORTS;
//加戴自动配置的元信息,配置文件为类路径中 META-INF 目录下的
// spring-autoconfigure -metadata. properties 文件
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMe
tadataLoader
. loadMetadata(this . beanClassLoader);
//封装将被引入的自动配置信息
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry
autoConfigurationMetadata, 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<String> configurations = getCandidateConfigurations (annotationMetadata,
attributes);
//对获得的注册配置类集合进行去重处理,防止多个项目引入同样的配置类 configurations =
removeDuplicates( configurations);
//获得炷解中被 excLude.或 excLudeName 所排除的类的集合
Set<String> 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方法第一段中。 如果开启自动配置功能,就继续执行后续操作;如果未开启,就返回空数组。代码如下。

@Override
public 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


Tags:AutoConfiguration   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
AutoConfiguration lmportSelector源码解析@EnableAutoConfiguration 的关键功能是通过@Import 注解导入的 ImportSelector 来完成的从 源 代码得知@lmport(AutoConfigurati...【详细内容】
2020-10-12  Tags: AutoConfiguration  点击:(105)  评论:(0)  加入收藏
▌简易百科推荐
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(1)  评论:(0)  加入收藏
程序是如何被执行的&emsp;&emsp;程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(9)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(19)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(23)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(24)  评论:(0)  加入收藏
一个项目的大部分API,测试用例在参数和参数值等信息会有很多相似的地方。我们可以复制API,复制用例来快速生成,然后做细微调整既可以满足我们的测试需求1.复制API:在菜单发布单...【详细内容】
2021-12-14  AutoMeter    Tags:AutoMeter   点击:(20)  评论:(0)  加入收藏
相关文章
    无相关信息
最新更新
栏目热门
栏目头条