【SpringBoot】Spring Boot自动配置概览

devtools/2024/9/22 13:47:05/
webkit-tap-highlight-color: rgba(0, 0, 0, 0);">

目录

  • 背景
  • 自动装配/自动配置
  • springboot是如何实现自动配置的
    • 核心注解
    • AutoConfigurationImportSelector 类的继承体系
      • Spring Boot 提供的条件注解
      • 示例
      • 注意版本

背景

  • 没有 Spring Boot 的情况下,我们引入第三方依赖之后,需要手动配置。

  • 比如需要手动将引入的第三方依赖通过 xml 配置或注解的方式注入到 Ioc 容器中,并可能需要对注入到Ioc容器中的bean进行一些配置,非常麻烦。

  • 但是,在Spring Boot 中,我们直接引入一个 starter 即可。例如:

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    

自动装配/自动配置

  • SpringBoot2.7以前定义了一套接口规范,这套规范规定:
    • SpringBoot 在启动时会扫描外部引用 jar 包中的 META-INF/spring.factories 文件,将文件中配置的类型信息加载到 Spring 容器(此处涉及到 JVM 类加载机制与 Spring 的容器知识),并执行类中定义的各种操作。
    • 对于外部 jar 来说,只需要按照 SpringBoot 定义的标准,就能将自己的功能装置进 SpringBoot
  • 引入 starter 之后,我们通过少量注解和一些简单的配置就能使用第三方组件提供的功能了
  • 所以说,其实自动装配可以简单的理解为:通过注解或者一些简单的配置就能在spring boot>spring boot的帮助下实现某款功能

springboot_19">springboot是如何实现自动配置的

核心注解

首先我们先来看一些 SpringBoot 项目的核心注解 @SpringBootApplication:
在这里插入图片描述

  • 点击 @SpringBootConfiguration 注解,发现这个注解其实就是一个配置注解,SpringBoot 把 @Configuration 注解做一个包装。

  • 所以说 @SpringBootApplication 是一个复合注解,大概就可以把 @SpringBootApplication 看作是这三个注解的集合:

    • @EnableAutoConfiguration:启用 SpringBoot 的自动配置机制。
    • @Configuration:允许在上下文中注册额外的 bean 或导入其他配置类,作用与applicationContext.xml 的功能相同。
    • @ComponentScan: 扫描包下的类中添加了@Component (@Service,@Controller,@Repostory,@RestController)注解的类 ,并添加的到spring的容器中,可以自定义不扫描某些 bean。如下图所示,容器中将排除TypeExcludeFilter和AutoConfigurationExcludeFilter。
      在这里插入图片描述
  • 也就是说,@EnableAutoConfiguration 是实现自动装配的核心注解,@EnableAutoConfiguratio的内部如下所示。
    在这里插入图片描述

  • 思考:AutoConfigurationImportSelector 类到底做了什么?

AutoConfigurationImportSelector 类的继承体系

在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 可以看出:AutoConfigurationImportSelector 类实现了 ImportSelector 接口,也就实现了这个接口中的 selectImports 方法

  • 该方法主要用于获取所有符合条件的类的全限定类名,需要为这些类创建对象并加载到 IoC 容器中
    在这里插入图片描述

  • 这里我们需要重点关注一下 getAutoConfigurationEntry方法,这个方法主要负责加载自动配置类的。该方法调用链如下:
    在这里插入图片描述

    java">protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {//第1步:判断自动装配开关是否打开if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY;}//第2步:用于获取注解中的exclude和excludeName。//获取注解属性AnnotationAttributes attributes = getAttributes(annotationMetadata); //第3步:获取需要自动装配的所有配置类,读取META-INF/spring.factories//读取所有预配置类List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);//第4步:符合条件加载//去掉重复的配置类configurations = removeDuplicates(configurations);//执行Set<String> exclusions = getExclusions(annotationMetadata, attributes);//校验checkExcludedClasses(configurations, exclusions);//删除configurations.removeAll(exclusions);//过滤configurations = getConfigurationClassFilter().filter(configurations);fireAutoConfigurationImportEvents(configurations, exclusions);//创建自动配置的对象return new AutoConfigurationEntry(configurations, exclusions);
    }
    
    • 第1步:判断自动装配开关是否打开。默认 spring.boot.enableautoconfiguration = true,可在 application.properties 或 application.yml 中设置。
    • 第2步:用于获取 EnableAutoConfiguration 注解中的 exclude 和 excludeName。
    • 第3步:从 META-INF/spring.factories 读取需要自动装配的所有配置类。所有 Spring Boot Starter 下的 META-INF/spring.factories 都会被读取到。
    • 第4步:spring.factories 中这么多配置,每次启动都要全部加载么?很明显,这是不现实的。我们 debug 到后面你会发现,configurations 的值变小了。。因为,这一步有经历了一遍筛选过滤,@ConditionOnXXX 中的所有条件都满足,该类才会生效。
      在这里插入图片描述

Spring Boot 提供的条件注解

  1. @ConditionalOnBean:当容器里有指定 Bean 的条件下
  2. @ConditionalOnMissingBean:当容器里没有指定 Bean 的情况下
  3. @ConditionalOnSingleCandidate:当指定 Bean 在容器中只有一个,或者虽然有多个但是指定首选 Bean
  4. @ConditionalOnClass:当类路径下有指定类的条件下
  5. @ConditionalOnMissingClass:当类路径下没有指定类的条件下
  6. @ConditionalOnProperty:指定的属性是否有指定的值
  7. @ConditionalOnResource:类路径是否有指定的值
  8. @ConditionalOnExpression:基于 SpEL 表达式作为判断条件
  9. @ConditionalOnJava:基于 Java 版本作为判断条件
  10. @ConditionalOnJndi:在 JNDI 存在的条件下差在指定的位置
  11. @ConditionalOnNotWebApplication:当前项目不是 Web 项目的条件下
  12. @ConditionalOnWebApplication:当前项目是 Web 项 目的条件下

示例

以redis为例,然后在当前springboot项目中双击Shift,在弹出的页面中搜索找到RedisAutoConfiguration类。

  • 由RedisAutoConfiguration类上面的注解可知,RedisAutoConfiguration类有一个bean加载控制的注解。也就是说,当前类要想加载成bean,必须在当前项目中导入RedisOperations这个类,也就是当前类加载成bean的触发条件,而RedisOperations这个类在我们导入的redis的依赖包中。
  • 在RedisAutoConfiguration类上方有一个 @EableConfigurationProperties 注解。进入@EableConfigurationProperties 注解里的RedisProperties类中,如下图所示, RedisProperties 类上方有一个 @ConfigurationProperties 注解,此注解用来将配置文件中前缀为 spring.redis 的配置值绑定到类中属性上。
  • 但是可以发现,RedisProperties类里很多属性已经配置了默认值。也就是说,如果 springboot 配置文件中没有配置值,则 springboot 会采用 RedisProperties 类中属性的默认值来作为redis这项技术的默认配置值。
    在这里插入图片描述

注意版本

spring.factories 功能在 SpringBoot 2.7 已经废弃,并且在 SpringBoot 3.0 移除。但机制还是类似的


http://www.ppmy.cn/devtools/31087.html

相关文章

精准测试-Vue前端调用链影响变更分析之一

Vue前端调用链影响变更分析之一 一、背景二、工具调研1、 工具介绍&#xff1a;2、工具使用 三、工具落地集成方案&#xff08;待后续补充&#xff09;变更影响较为简单的实现变更影响较为复杂的实现1、全局关系数据库的构建2、变更影响的简单实现3、变更影响的复杂实现 一、背…

Java实现裁剪PDF

目录 安装Java PDF库 Java裁剪PDF页面 Java裁剪PDF页面并将结果保存为图片、HTML、Excel等格式 裁剪PDF页面是一项常见的任务&#xff0c;它可以用来调整文档的尺寸和去除不需要的边距或白边。通过裁剪页面&#xff0c;你可以优化文档的布局和展示效果&#xff0c;使其更符合…

pyqt5报错

pyqt5报错解决 文章目录 pyqt5报错解决环境错误一错误二 环境 Python 3.9 Pyqt5 5.15 错误一 File "try.ui", line 1<?xml version"1.0" encoding"UTF-8"?>^syntaxError: invalid syntax报这个错的&#xff0c; 把PyUIC的Arguments参…

如何查看我的Docker 容器和 `app.py` 脚本有足够的权限来读取 `config.json` 文件

要检查 Docker 容器和 app.py 脚本是否具有读取 config.json 文件的足够权限&#xff0c;你可以按照以下步骤操作&#xff1a; 检查宿主机上的文件权限&#xff1a; 在宿主机上&#xff0c;使用 ls -l 命令查看 config.json 文件的权限。 ls -l /path/to/config.json确保该文件…

CSS中文本样式(详解网页文本样式)

目录 一、Text介绍 1.概念 2.特点 3.用法 4.应用 二、Text语法 1.文本格式 2.文本颜色 3.文本的对齐方式 4.文本修饰 5.文本转换 6.文本缩进 7.color&#xff1a;设置文本颜色。 8.font-family&#xff1a;设置字体系列。 9.font-size&#xff1a;设置字体大小。…

Linux学习之IP协议

前言&#xff1a; 在学习IP协议i前&#xff0c;我们其实知道网络协议栈是一层层的&#xff0c;上层封装好之后就传给下层&#xff0c;对于我们治安学习到的TCP协议&#xff0c;在对数据进行封装之后&#xff0c;并不是直接就将数据进行传输&#xff0c;而是交给下一层网络层进…

如何用TL431做恒流电路

主要内容 如何通过TL431恒流驱动LED 领取资料&#xff1a;关注并后台回复&#xff1a;粉丝群 正文 01 基本原理 如上图&#xff0c;TL431加上一个NPN三极管&#xff0c;即可实现LED恒流驱动&#xff0c;基本原理是利用TL431的REF极与阳极A之间电压恒定2.5V来调控输出电流。当…

Vue 2 中组件详解

什么是组件&#xff1f; 在Vue中&#xff0c;组件是可复用的Vue实例&#xff0c;每个组件都可以拥有自己的模板、脚本和样式。通过组件化&#xff0c;我们可以将页面拆分为多个独立的、可复用的部分&#xff0c;使得代码更易于维护和扩展。 创建组件 在Vue 2中&#xff0c;我们…