IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringBoot自动装配原理 -> 正文阅读

[Java知识库]SpringBoot自动装配原理

@SpringBootApplication注解
对这个注解详细大家一定非常熟悉了。再来好好看看这个注解。

我们点进该注解,发现它由多个注解构成。
这种注解 注解注解的方式实在看着让人头疼。
在这里插入图片描述

  • @ComponentScan 就不多赘述了,就是一个自动扫描的注解。应该都很熟悉

我们主要看这两个SpringBoot的注解,也就是 @SpringBootConfiguration和@EnableAutoConfiguration
我们点进 @SpringBootConfiguration注解发现他里面没有太多东西,只是对 @Configuration注解进行了一个封装。
简而言之,它就是一个 @Configuration 注解而已。
在这里插入图片描述

那只剩下@EnableAutoConfiguration注解可以做文章了,该注解水特别深

点进该注解后,我们看到有 @AutoConfigurationPackage和 @Import两个注解
在这里插入图片描述

  • @AutoConfigurationPackage注解没什么好说的,和它的名字一样其作用就是自动配置包。也就是让该注解标记的类所在包及下面所有子包里面的所有组件扫描到Spring容器中。
  • @Import注解则导入了一个AutoConfigurationImportSelector类,我们点进去看一下这个类做了什么。

发现该类实现了许多接口,我们把目光放到 DeferredImportSelector接口上,点进这个接口,发现它继承了ImportSelector接口。再往里点,发现ImportSelector接口 它有一个selectImports方法,到头了。
在这里插入图片描述

我们回到AutoConfigurationImportSelector类,看看selectImports这个方法被如何重写了。

在这里插入图片描述

首先 if判断会确认系统是否禁用了自动配置的功能。如果禁用了就会 return一个常量,该常量是一个空数组。也就无法注入bean了。
在这里插入图片描述
再往下能看到调用了一个 getAutoConfigurationEntry方法,我们看看这个方法干了什么。

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    // 判断是否允许自动装配 若不允许则直接返回空集 默认返回true
	if (!isEnabled(annotationMetadata)) {
		return EMPTY_ENTRY;
	}
    //getAttributes方法获得 @EnableAutoConfiguration注解中的属性exclude、excludeName等。
	AnnotationAttributes attributes = getAttributes(annotationMetadata);
    // ==又一关键方法== 该方法用于得到spring.factories文件EnableAutoConfiguration相关的自动配置类
	List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
    // 移除重复的配置类
	configurations = removeDuplicates(configurations);
    // 得到要排除的自动配置类
	Set<String> exclusions = getExclusions(annotationMetadata, attributes);
    // 检查要被排除的配置类
	checkExcludedClasses(configurations, exclusions);
    // 将要排除的配置类全部移除
	configurations.removeAll(exclusions);
    // 过滤操作,避免内存浪费
	configurations = getConfigurationClassFilter().filter(configurations);
    // 获取了符合条件的自动配置类后通知监听器来记录符合条件的自动配置类
	fireAutoConfigurationImportEvents(configurations, exclusions);
    // 将符合条件和要排除的自动配置类封装进AutoConfigurationEntry对象,并返回
	return new AutoConfigurationEntry(configurations, exclusions);
}

AutoConfigurationEntry方法主要用来获取符合条件的自动配置类,和避免加载不需要的自动配置类(会造成内存的浪费)。

我们再来看看用于得到所有自动配置类的getCandidateConfigurations方法。

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
    getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "+ "are using a custom packaging, make sure that file is correct.");
    return configurations;
}

是不是又看到一个十分熟悉的方法loadFactoryNames(); ,我们把镜头交到loadFactoryNames,再回顾一遍 SpringBoot是如何从 META-INF/spring.factories中加载指定 key的 value的。

public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
    // 获取检索类的全限定名
    String factoryTypeName = factoryType.getName();
    // 进行spring.factories文件集的加载、检索操作,并构以空集为兜底返回数据
    return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}

debug,看看要从META-INF/spring.factories中加载的类的key,如下图所示:org.springframework.boot.autoconfigure.EnableAutoConfiguration
在这里插入图片描述
回到selectImports()方法,debug,跳过List configurations = getCandidateConfigurations(annotationMetadata,attributes);看一下configurations
在这里插入图片描述
竟然有一百多个,那这些类都在哪里呢?看spring-boot-autoconfigure(当然在SpringBoot的工程中,也不止这一个依赖包中存在该配置文件)工程下的META-INF/spring.factories,我们能看到org.springframework.boot.autoconfigure.EnableAutoConfiguration定义了一大堆。
在这里插入图片描述

继续看
Set exclusions = getExclusions(annotationMetadata, attributes);方法,该方法是排除主类上
@SpringBootApplication注解上排除的自动装配的类。比如我们在该注解上排除我们自定义starter的自动装配的类,
@SpringBootApplication(exclude = {com.demo.starter.config.DemoConfig.class})
(当然也可以用excludeName进行排除),那么在后面
configurations.removeAll(exclusions);
方法中将会删除我们的com.demo.starter.config.DemoConfig.class

java@ConditionalOnBean:容器中有指定的Bean
@ConditionalOnClass:当类路径下有指定的类
@ConditionalOnExpression:基于SpEL表达式作为判断条件
@ConditionalOnJava:基于JVM版本作为判断条件
@ConditionalOnJndi:在JNDI存在的条件下查找指定的位置
@ConditionalOnMissingBean:当容器中没有指定Bean的情况下
@ConditionalOnMissingClass:当类路径下没有指定的类
@ConditionalOnNotWebApplication:当前项目不是Web项目
@ConditionalOnProperty:配置文件中指定的属性是否有指定的值
@ConditionalOnResource:类路径下是否有指定的资源
@ConditionalOnSingleCandidate:当指定Bean在容器中只有一个,或者虽然有多个但是指定首选Bean
@ConditionalOnWebApplication:当前项目是Web项目的条件下
在这里插入图片描述
上图这种没有满足@ConditionXXX注解的自动配置类,就不会被注入到IoC容器中

在这里插入图片描述
而这种满足了@ConditionXXX的自动配置类就会被导入到IoC容器中了

除了这些条件注解,我们还有一些注解可以讲

找到EnableConfigurationProperties注解,点进它这个类。
在这里插入图片描述
点进来后我们能看到一个前缀(spring.mvc),和非常多的属性。

在这里插入图片描述
不难猜到这些属性就是对应的我们能够在application.yaml配置文件中自定义配置的一些配置。

在这里插入图片描述
我们来看一下ConfigurationProperties这个注解

这个注解会将我们配置文件中的配置项和它prefix参数中的前缀进行匹配。

如果能够匹配到的话,就会将我们配置文件的配置项读到其前缀相匹配的类中
在这里插入图片描述
而EnableConfigurationProperties注解又将该类注入到了我们的IoC容器中,那我们启动SpringBoot主程序时也就自然而然的实现了自定义配置的操作。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:17:51  更:2022-03-10 22:17:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:52:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码