SpringBoot自动配置原理

2023-10-27

说明:在阅读本篇文章之前建议大家先详细学习一下spring的相关知识,有助于更深刻的理解spirngboot的配置原理。

 

目录

一、什么是springboot自动配置

二、Starter组件 

三、三大注解

四、@EnableAutoConfiguration

五、SpringFactoriesLoader


前言:在springboot的启动类中可以看到@SpringBootApplication注解,它是SpringBoot的核心注解,也是一个组合注解。其中@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三个注解尤为重要。今天我们就来浅析这三个注解的含义。

一、什么是springboot自动配置

 Spring Boot通过@EnableAutoConfiguration注解开启自动配置,对jar包下的spring.factories文件进行扫描,这个文件中包含了可以进行自动配置的类,当满足@Condition注解指定的条件时,便在依赖的支持下进行实例化,注册到Spring容器中。
 通俗的来讲,我们之前在写ssm项目时候,配置了大量坐标和配置内容,搭环境的过程在项目开发中占据了大量时间,Spring Boot的最大的特点就是简化了各种xml配置内容,所以springboot的自动配置就是用注解来对一些常规的配置做默认配置,简化xml配置内容,使你的项目能够快速运行。
springboot核心配置原理:

  • 自动配置类都存放在spring-boot-autoconfigure-版本号.jar下的org.springframework.boot.autoconfigure中
  • 当我们在application.properties中配置debug=true后启动容器。可以看到服务器初始化的初始化配置
  • DispatcherServletAutoConfigratio 注册前端控制器
  • EmbeddedServletContainerAutoConfiguration注册容器类型
  • HttpMessageConvertersAutoConfiguration注册json或者xml处理器
  • JacksonAutoConfiguration注册json对象解析器
  • 如果加入其他功能的依赖,springBoot还会实现这些功能的自动配置 

 

二、Starter组件 

 Starter组件是可被加载在应用中的Maven依赖项项。只有在Maven配置中添加对应的依赖配置,即可使用对应的Starter组件。例如,添加spring-boot-starter-web依赖,就可以用于构建REST API服务,其包含了SpringMVC和Tomcat内嵌容器。

一个完整的Starter组件包括以下两点:

  • 提供自动配置功能的自动配置模块
  • 提供依赖关系管理岗功能的组件模块,即封装了组件所有功能,开箱即用。

spring-boot-starter-web依赖源码

package org.springframework.boot.autoconfigure.web.servlet;
 
@Configuration
@ConditionalOnClass({ServletRequest.class})
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@EnableConfigurationProperties({ServerProperties.class})
@Import({ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class})
public class ServletWebServerFactoryAutoConfiguration {
    ......
}
@

三、三大注解


@SpringBootConfiguration:继承自Configuration,支持JavaConfig的方式进行配置。

@EnableAutoConfiguration:本文重点讲解,主要用于开启自动配置。

@ComponentScan:自动扫描组件,默认扫描该类所在包及其子包下所有带有指定注解的类,将它们自动装配到bean容器中,会被自动装配的注解包括@Controller、@Service、@Component、@Repository等。也可以指定扫描路径。


四、@EnableAutoConfiguration

 这个注解是帮助我们自动加载默认配置的,它里面有两个关键注解@AutoConfigurationPackage和@Import,我们来详细了解@Import注解。

 

@Override
	public String[] selectImports(AnnotationMetadata annotationMetadata) {
		//检查自动配置功能是否开启,默认开启
		if (!isEnabled(annotationMetadata)) {
			return NO_IMPORTS;
		}
		//加载自动配置的元信息
		AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
				.loadMetadata(this.beanClassLoader);
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		//获取候选配置类
		List<String> configurations = getCandidateConfigurations(annotationMetadata,
				attributes);
		//去掉重复的配置类
		configurations = removeDuplicates(configurations);
		//获得注解中被exclude和excludeName排除的类的集合
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
		//检查被排除类是否可实例化、是否被自动注册配置所使用,不符合条件则抛出异常
		checkExcludedClasses(configurations, exclusions);
		//从候选配置类中去除掉被排除的类
		configurations.removeAll(exclusions);
		//过滤
		configurations = filter(configurations, autoConfigurationMetadata);
		//将配置类和排除类通过事件传入到监听器中
		fireAutoConfigurationImportEvents(configurations, exclusions);
		//最终返回符合条件的自动配置类的全限定名数组
		return StringUtils.toStringArray(configurations);
	}

@Import(AutoConfigurationImportSelector.class)注解,这里导入AutoConfigurationImportSelector类。这个类中有一个非常重要的方法——selectImports(),它几乎涵盖了组件自动装配的所有处理逻辑,包括获得候选配置类、配置类去重、排除不需要的配置类、过滤等,最终返回符合条件的自动配置类的全限定名数组。
 

五、SpringFactoriesLoader

spring-core包里定义了SpringFactoriesLoader类,这个类实现了检索META-INF/spring.factories文件,并获取指定接口的配置的功能。在这个类中定义了两个对外的方法:

  • loadFactories 根据接口类获取其实现类的实例,这个方法返回的是对象列表。
  • loadFactoryNames 根据接口获取其接口类的名称,这个方法返回的是类名的列表。

上面的两个方法的关键都是从指定的ClassLoader中获取spring.factories文件,并解析得到类名列表,具体代码如下:

public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
    String factoryClassName = factoryClass.getName();
    try {
        Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
        List<String> result = new ArrayList<String>();
        while (urls.hasMoreElements()) {
            URL url = urls.nextElement();
            Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
            String factoryClassNames = properties.getProperty(factoryClassName);
            result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
        }
        return result;
    }
    catch (IOException ex) {
        throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
                "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
    }
}

由代码可知,在这个方法中会遍历整个ClassLoader中所有jar包下的spring.factories文件。也就是说我们可以在自己的jar中配置spring.factories文件,不会影响到其它地方的配置,也不会被别人的配置覆盖。
spring.factories的是通过Properties解析得到的,所以我们在写文件中的内容都是安装下面这种方式配置的:com.xxx.interface=com.xxx.classname

最后希望大家在学习的过程中,能够多了解实现各种功能的基本原理,有助于提高学习效率。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot自动配置原理 的相关文章

随机推荐

  • Fiddler在PC/台式对Android进行抓包

    Fiddler是一个常用的http抓包工具 它能够记录电脑和移动端的进出数据 而且操作十分简便 下面主要介绍在台式机上Fiddler如何对Android进行数据抓包 本人使用的Fiddler版本为v5 0 文章主要知识点如下 1 手机连接台
  • Python读写操作Excel数据详解

    自从学了Python后就逼迫自己不用Excel 所有操作用Python实现 目的是巩固Python 与增强数据处理能力 这也是我写这篇文章的初衷 废话不说了 直接进入正题 1 前期准备 1 1 初识Excel Microsoft Excel
  • iphone备忘录突然没了_玩转这8个技巧,让你成为iPhone老司机

    最近精选君遇到了一件超级尴尬的事情 用苹果手机下载安装软件的时候 突然识别不出我的指纹 迫于无奈只好输入密码 可是尴尬的是 Apple ID的密码忘记的一干二净 不知道你是否也遇到过这样的窘境 今天精选君给大家分享8个苹果手机小技巧 让你避
  • EG3D: Efficient Geometry-aware 3D Generative Adversarial Networks [2022 CVPR]

    长期以来 仅使用单视角二维照片集无监督生成高质量多视角一致图像和三维形状一直是一项挑战 现有的三维 GAN 要么计算密集 要么做出的近似值与三维不一致 前者限制了生成图像的质量和分辨率 后者则对多视角一致性和形状质量产生不利影响 在这项工作
  • 这些 Shell 分析服务器日志命令集锦,收藏好

    自己的小网站跑在阿里云的ECS上面 偶尔也去分析分析自己网站服务器日志 看看网站的访问量 看看有没有黑阔搞破坏 于是收集 整理一些服务器日志分析命令 大家可以试试 1 查看有多少个IP访问 awk print 1 log file sort
  • React组件设计实践总结04 - 组件的思维

    在 React 的世界里 一切都是组件 组件可以映射作函数式编程中的函数 React 的组件和函数一样的灵活的特性不仅仅可以用于绘制 UI 还可以用于封装业务状态和逻辑 或者非展示相关的副作用 再通过组合方式组成复杂的应用 本文尝试解释用
  • Java并发编程实战——线程池ThreadPoolExecutor实现原理

    文章目录 为什么要使用线程池 线程池的工作原理 线程池的创建 BlockingQueue execute 方法 如何合理配置线程池参数 之前在 RabbitMQ池化方案中提到过线程池 本节我们加深理解 为什么要使用线程池 在实际使用中 线程
  • sessionID的本质、保存在哪里?

    一 客户端用cookie保存了sessionID 客户端用cookie保存了sessionID 当我们请求服务器的时候 会把这个sessionID一起发给服务器 服务器会到内存中搜索对应的sessionID 如果找到了对应的 session
  • 如何在ios真实设备上调试程序,真机测试软件信任问题

    所用机型为iPhone 13 本文主要讨论如何 信任开发人员 也就是app传到设备上后打不开的问题 全过程原链接奉上 https blog csdn net cunjie3951 article details 106923536 ops
  • docker查看日志的方式

    docker查看日志的几个方式 1 docker logs tail 1000 容器名称 查看容器前多少行的日志 推荐 2 docker 容器启动后 可以进入以下位置查看日志 var lib docker containers 容器ID 容
  • 【C语言】指针(一) — 指针的定义

    目录 一 什么是指针 二 指针变量的定义 三 指针变量的赋值 四 通过指针访问变量 一 什么是指针 以我的理解 指针就是存储地址的变量 在C语言中 对于变量的访问形式之一就是先求出变量的地址 然后再通过地址对它进行访问 这就是指针及指针变量
  • YoloV8改进策略:VanillaNet极简主义网络,大大降低YoloV8的参数

    文章目录 摘要 论文翻译 论文摘要 1 简介 2 普通的神经网络架构 3 普通网络的训练 3 1 深度训练策略 3 2 串联的激活函数 4 实验 4 1 消融研究 4 2 注意可视化 4 3 与SOTA体系结构的比较 4 4 COCO实验
  • 在一个普通的html文件中引入es6

    我们在日常开发中 如果我们使用es5则可以直接在浏览器里面写JavaScript脚本 一点问题也没有 但是在写es6语法的JavaScript代码的时候 我们就需要引入babel翻译器了
  • pytorch中的dropout

    为了防止过拟合 我们可以对网络实行dropout操作 有三种方法可以实现 torch nn functional dropout input p training self training 该种方法实现时必须标明training的状态为s
  • 测试学习13(正交表、测试用例力度、软件缺陷)

    正交表 从全面实验中挑选出有代表性的点进行测试 均匀分散 整齐可比 高效率 快速 经济的方法 正交排列法 正交实验设计 特点 均匀分散 齐整可比 正交表的概念 使用步骤 案例1 映射到选择好的正交表中 使用正交表的局限性 混合正交表 在实际
  • replaceAll、replace、replaceFirst(字符串多个元素替换)

    一 替换字符串中的多个字符 前言 Java中替换字符串可以用replace和replaceAll这两种 区别是 replace的参数是char和CharSequence 即可以支持字符的替换 也支持字符串的替换 CharSequence即字
  • flask_wtf中的参数介绍(StringField,PasswordField...)

    WTForms支持的HTML标准字段 字段类型 说 明 StringField 文本字段 TextAreaField 多行文本字段 PasswordField 密码文本字段 HiddenField 隐藏文本字段 DateField 文本字段
  • 【Java基础】IO流(二)

    个人简介 gt 个人主页 是Lay的主页 gt 学习方向 JAVA后端开发 gt 种一棵树最好的时间是十年前 其次是现在 gt 往期文章 Java基础 File类 IO流 gt 喜欢的话麻烦点点关注喔 你们的支持是我的最大动力 目录 1 字
  • Kali Linux网络攻击

    文章目录 一 Kali Linux 使主机和虚拟机IP处于同一网段 1 关机 点击edit 虚拟机 2 网络连接 选择桥接bridge模式 3 现在开机 就和主机在同一网段下 可以fping g查找其它的IP地址了 二 查看局域网下所有ip
  • SpringBoot自动配置原理

    说明 在阅读本篇文章之前建议大家先详细学习一下spring的相关知识 有助于更深刻的理解spirngboot的配置原理 目录 一 什么是springboot自动配置 二 Starter组件 三 三大注解 四 EnableAutoConfig