当前位置: 首页 > news >正文

Spring Boot 原理篇

Spring Boot 原理篇

Spring系列框架是目前全世界最流行的java开发框架,可以说**Spring是现代java开发的基石**,它划分了多个子框架,如:SpringDataSpringBootSpringCloudSpringAISpringFramework…其中SpringFramework是所有模块的基础。

分析Spring Boot原理可以使我们更好的熟练使用Spring Boot,并汲取其优秀的设计思想。

若直接使用SpringFramework,依赖配置将非常繁琐,每次引入一个依赖,都要找到其配套的所有依赖及其版本。基于此,Spring官方基于SpringFramework4.0之后版本推出一个全新的框架SpringBoot,通过SpringBoot简化SpringFrmework的开发(注意是简化,不是替代,也就是说SpringBootSpringFramework的上层框架),而SpringBoot又是Spring家族中最流行的框架,Spring官方也推荐直接使用SpringBoot构建项目。

使用SpringBoot构建并开发项目会使项目开发更方便快捷,主要原因就是最核心的两个功能:起步依赖、自动配置。解析SpringBoot的原理,就是来解析起步依赖自动配置的原理

  • 通过起步依赖,可以大大简化pom.xml文件中依赖的配置,解决SpringFramework中依赖配置繁琐的问题。
  • 通过自动配置,可以大大简化框架使用过程中Bean的声明及配置。

注:下文核心细节的知识点用图标表示重要程度

  • ⭐:核心,作为使用Sping Boot的上层开发者必须要掌握的

  • 🍀:了解,不需要深入学习,了解即可,学习它可更好了解Spring Boot的底层设计与实现

起步依赖

我们只需引入起步依赖,常见的基本依赖都会随之引入。

SpringBoot之前,光使用SpringFramework,项目开始需要引入很多基本依赖,非常地繁琐。
在这里插入图片描述

使用SpringBoot创建项目后,引入一个起步依赖(以Web开发为例:spring-boot-start-web)即可将许多基本依赖会随之引入:
在这里插入图片描述
原理也很简单,就是maven的依赖传递。所谓依赖传递指:若A依赖B,B依赖C,引入A依赖,B、C依赖也会随之引入。

自动配置

自动配置:当spring启动后,一些配置、bean对象(引入的依赖中存在)自动存入到IOC容器中,不需要我们手动声明,从而简化了开发,省去了繁琐的配置操作。

研究SpringBoot的自动配置,其实重点需要研究在Spring启动后

  1. SpringBoot是如何将依赖jar包中的Bean对象注入到IOC容器中的?
  2. 它是如何识别依赖jar包中哪些对象是需要加载到IOC容器的成为Bean对象?
  3. 加载Bean对象的规则是怎么样的?加载的流程又是怎么样的?

包扫描与导入

包扫描:Spring中,通过@Commonent注解及其衍生注解可以实现自定义Bean对象的定义,Spring启动时默认会扫描启动类所在包及其子包中的所有类来实现寻找bean对象,并将其加载到IOC容器中。也可使用@ComponentScan添加参数实现自定义扫描范围,例如:

@ComponentScan({"com.example","com.gezishan","org.mybatis"})
@SpringBootApplication
public calss SpringbootWebApplication{}

如果将依赖jar包中的Bean对象加载到IOC容器也使用这种方式,配置将非常繁琐,依赖多了,包扫描的范围也很大,但Bean对象并没有多少,这样效率就很低。

Spring也提供了另一种将Bean对象加载到IOC容器的方法,那就是导入

导入:Spring中,通过@Import注解指定**Class参数**实现导入,使用@Import导入的类会被加载进IOC容器,导入类的类型有:

  • 导入普通类,指定的该普通类会被加载进IOC容器
  • 导入配置类,指定的配置类所配置的所有Bean对象会被加载进IOC容器
  • 导入 ImportSlector接口实现类(下文称自动配置选择器),该实现类的slectImporte()方法返回的字符串类名数组对应的类会被加载进IOC容器
//导入一个普通类和一个配置类以及ImportSlector接口实现类
@Import({TokenParser.class,HeaderConfig.class,MyImportSelector.class})  
@SpringBootApplication
public calss SpringbootWebApplication{}
ImportSlector接口

翻看源码

在这里插入图片描述

该接口有一个必须实现的方法slectImporte(),返回值是一个字符串数组,表示需要交给IOC容器管理的类名数组,可以将Bean对象的全类名封装成数组中返回。

配置管理:需要交出去的Bean对象很多时,可以写一份文件列出要交出去的Bean对象,再在slectImporte()方法中读取文件中所有的Bean对象全类名。这样配置管理就更加方便,代码也更清晰,不用在@Import中罗列那么多类名。

对于第三方的jar包中的Bean对象,通常由第三方的开发者自己定义导入。

🍀 @EnableXxxx注解

@EnableXxxx注解是一个泛称,它表示第三方提供的注解,通常封装了@Import注解

启动流程

⭐@springBootApplication

@springBootApplication注解是SpringBoot项目的核心注解,它标识在SpringBoot工程的启动类上,该注解由三部分组成:

  1. @SpringBootConfiguration:该注解与@Configuration相同,用来声明当前类也是一个配置类。
  2. @ComponentScan:组件扫描,默认扫描当前启动类所在包及其子包内的所有类文件,用于将自定义的Bean对象加载到IOC容器。
  3. @EnableAutoConfigurationSpringBoot实现自动化配置的核心注解,用于将依赖jar包中的Bean对象加载到IOC容器。

翻看源码

在这里插入图片描述

⭐@EnableAutoConfiguration

@EnableAutoConfiguration 的作用是开启自动配置机制,是自动配置的核心,其实现依赖两个关键步骤

  1. @Import({AutoConfigurationImportSelector.class})

通过@import导入AutoConfigurationImportSelector类(自动配置选择器),它通过slectImporte()方法返回待加载的Bean对象类名数组

  1. 加载自动配置类的候选名单

AutoConfigurationImportSelectorslectImporte()方法的内部会执行以下步骤

  • 读取spring.factories文件:从所有类路径下的META-INF/spring.fectories文件中加载要自动配置的类。

MyBatisPlusspring.factories文件为例:

在这里插入图片描述

  • 筛选有效的自动配置类:通过条件装配注解(@ConditionalXxxx系列注解)和AutoConfigurationMetadata
⭐类路径ClassPath

类路径(ClassPath) 指的是 Java 程序运行时,JVM 用于查找类(.class字节码文件)、资源(如配置文件、图片等)的路径。这些路径在编译、打包和运行时会被 JVM 识别并加载。


开发阶段(IDE 中)

MavenGradle 项目的标准目录结构中,类路径对应:

  • src/main/java:存放 Java 源代码,编译后的 .class 文件会被输出到 target/classes(Maven)或 build/classes(Gradle)。

  • src/main/resources:存放资源文件(如 application.propertiesMETA-INF/spring.factories 等),这些文件会被直接复制到 target/classesbuild/classes成为类路径的一部分

    例如,若在 src/main/resources/META-INF/ 下创建 spring.factories,编译后会被放入 target/classes/META-INF/spring.factories,此时该文件处于类路径中,可被 Spring Boot 扫描到。


打包后(Jar/War 包中)

当项目打包为 JarWar 包后,类路径对应包内的根目录:

  • Jar 包中,META-INF/spring.factories 通常位于 Jar 包的根目录下的 META-INF 文件夹中(如 xxx.jar!/META-INF/spring.factories)。

​ 例如,Spring Boot 内置的 spring-boot-autoconfigure.jar 中就包含 META-INF/spring.factories,定义了默认的自动配置类列表。


依赖包中的类路径

jar包中依赖的jar包会通过依赖传递,也成为项目的类路径。


Spring Boot 在启动时会扫描所有依赖 jar 包及当前项目自身类路径下spring.factories文件,汇总其中的配置信息

⭐ @ConditionalXxxx系列注解

自动配置类并非在候选名单中就无条件生效,它可通过注解实现动态装配,满足条件才会被注册为Bean对象。

@Conditional注解是条件装配注解,作用是按照一定的条件进行判断,在满足给定条件后才会注册对应的Bean对象到IOC容器中。

使用位置:方法、类

@Conditional本身是一个父注解,它派生出大量的子注解用于具体的条件判断,以下是常用的几个:

注解作用
@ConditionalOnClass类路径中存在指定类时生效
@ConditionalOnMissingClass类路径中不存在指定类时生效
@ConditionalOnBean容器中存在指定 Bean 时生效
@ConditionalOnMissingBean容器中不存在指定 Bean 时生效
@ConditionalOnProperty配置文件中存在指定属性且值匹配时生效
@ConditionalOnWebApplication应用是 Web 应用时生效
@ConditionalOnNotWebApplication应用不是 Web 应用时生效
  • @ConditionalOnClass:判断环境中有对应字节码文件,才注册bean到IOC容器。
@Configuration
public class HeaderConfig{@Bean@ConditionalOnClass(name = "io.jsonwebtoken.Jwts")  //判断环境中存在Jwts类才会注册此Bean对象public HeaderParser headerParser(){return new HeaderParser();}
}
  • @ConditionalOnMissingBean:判断环境中没有对应dean(可根据类型或名称判断),才注册beanIOC容器。
@Configuration
public class HeaderConfig{@Bean@ConditionalOnMissingBean  //判断环境中不存在此类型的Bean,才会注册此Bean对象。也可指定类型(使用注解的value属性)或名称(使用注解的name属性)判断public HeaderParser headerParser(){return new HeaderParser();}
}
  • @ConditionalOnProperty:判断application配置文件中有对应属性和值,才注册beanIOC容器。
@Configuration
public class HeaderConfig{@Bean@ConditionalOnProperty(name="name",havingValue="gezishan")  //判断配置文件中存在属性为"name",属性值为"gezishan"的配置项,才会注册此Bean对象public HeaderParser headerParser(){return new HeaderParser();}
}

除此之外还有许多派生注解:

在这里插入图片描述

🍀 AutoConfigurationMetadata

核心作用

AutoConfigurationMetadataSpring Boot 自动配置过程中用于存储和提供自动配置类条件信息元数据容器,它的核心作用是优化自动配置类的条件判断效率,避免在类路径扫描和条件校验时进行不必要的类加载或反射操作。

​ 在 Spring Boot 自动配置中,大量自动配置类(如 WebMvcAutoConfigurationDataSourceAutoConfiguration 等)通过 @ConditionalXxxx 系列注解(如 @ConditionalOnClass@ConditionalOnMissingClass)控制是否生效。这些条件判断通常需要检查类路径中是否存在某个类,或某个类是否有特定方法等。

如果每次直接通过反射或类加载器实时检查,会有两个问题:

  1. 性能开销:频繁的类加载和反射操作会降低启动速度。
  2. 潜在冲突:某些类可能在检查时被提前加载,导致后续逻辑异常。

数据来源

AutoConfigurationMetadata 的出现就是为了预先生成并缓存这些条件判断所需的元数据,在自动配置阶段直接读取元数据,避免实时检查,提升效率。

AutoConfigurationMetadata 的元数据来自于编译期生成的 META-INF/spring-autoconfigure-metadata.properties 文件

这个文件由 Spring Boot 提供的 spring-boot-autoconfigure-processor 注解处理器在项目编译时自动生成,内容是对所有自动配置类的条件注解信息的预处理结果

例如,对于注解了 @ConditionalOnClass({DataSource.class})DataSourceAutoConfiguration,编译后会在 spring-autoconfigure-metadata.properties 中生成类似如下的条目:

# 格式:自动配置类全类名.条件类型=值
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration.ConditionalOnClass=javax.sql.DataSource

核心步骤

  1. 快速条件校验

    AutoConfigurationImportSelector 筛选自动配置类时,会先通过 AutoConfigurationMetadata 读取预存的条件信息(如需要检查的类名),而非直接加载类。只有元数据指示 “可能符合条件” 时,才会进一步通过类加载器验证,减少不必要的类加载。

  2. 缓存元数据

    AutoConfigurationMetadata 会将 spring-autoconfigure-metadata.properties 中的内容加载到内存中,形成键值对缓存,供自动配置过程中快速查询

  3. 支持多种条件类型

    除了 @ConditionalOnClass,它还能处理 @ConditionalOnMissingClass@ConditionalOnResource 等注解的元数据,例如:

    # 检查是否缺少某个类
    org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.ConditionalOnMissingClass=org.springframework.web.reactive.DispatcherHandler
    # 检查是否存在某个资源
    org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration.ConditionalOnResource=classpath:org/hibernate/cache/ spi/RegionFactory.class
    

使用场景

作为开发者,我们通常不需要直接操作 AutoConfigurationMetadata,但了解它的存在有助于理解自动配置的效率优化机制

  • 当自定义自动配置类时,只要在项目中引入 spring-boot-autoconfigure-processor 依赖(通常已包含在 spring-boot-starter 中),编译时就会自动生成元数据文件,无需手动干预。
  • 若需排查自动配置类未生效的原因,可查看 spring-autoconfigure-metadata.properties 中的元数据,确认条件判断的预期值是否与实际环境一致。

⭐个性化配置

配置绑定 @ConfigurationProperties

自动配置类通常会通过 @ConfigurationProperties 注解,将配置文件(如 application.yaml)中的属性与 Java 类绑定,实现配置的动态注入。

示例DataSourceProperties 绑定数据库配置:

@ConfigurationProperties(prefix = "spring.datasource") // 绑定前缀为spring.datasource的配置
public class DataSourceProperties {private String url;private String username;private String password;// getters/setters
}

配置文件 application.properties 中可直接设置:

spring:datasource:url: jdbc:mysql://localhost:3306/testusername: rootpassword: 123456

自动配置的优先级:用户配置 > 自动配置

SpringBoot 遵循用户配置优先于自动配置的原则(个性先于全局):

  • 若用户手动定义了某个 Bean(如 @Bean 注解),则自动配置类中通过 @ConditionalOnMissingBean 标注的同名 Bean 会被忽略。
  • 例如:用户自定义了 DataSource 类型的 Bean,则 DataSourceAutoConfiguration 中自动配置的数据源会失效。

Starter规范

Spring项目中的Starter就是前面讲得起步依赖。

  • SpringBoot有自带的Starter,如:spring-boot-starter-webspring-boot-starter-aop等(一般规范:模块名在后)。
  • 很多第三方库也有对应的SpringBootStarter,如:mybatis-spring-boot-starterpagehelper-spring-boot-starter等(一般规范:模块名在前)。

Starter一般用于实现自动装配的配置,通过Starter可实现快速适配Spring项目,当然,也有不少第三方库没有Starter,我们可以通过自己写Starter来实现对第三方库中的一些对象工具进行Bean声明等配置,以实现快速适配Spring项目,并实现组件化复用。在实际开发中,经常会定义一些公共组件,提供给各个项目团队使用。在SpringBoot项目中,一般会将这些组件封装为Starter

一般Starter中需要引入一份spring-boot-autoconfigure依赖以实现对Bean对象的自动配置:

在这里插入图片描述

我们先来分析一下mybatis-spring-boot-starter依赖的jar包:

在这里插入图片描述

目录结构如上图所示,mybatisstarter依赖jar包中没有一行代码,其中有一些配置文件,其pow.xml文件引入了很多有关mybatis操作的依赖:
在这里插入图片描述
包括:

  • 起步依赖spring-boot-starter,使用spring提供的注解@Bean@Configurition及其他基本功能实现对mybatisBean的配置等。
  • 起步依赖spring-boot-starter-jdbc,使用spring-boot封装的jdbc功能,实现对数据库的操作
  • mybatis依赖,实现mybatis的核心功能
  • mybatis-spring依赖,基于springmybatis的功能
  • mybatis-spring-boot-autoconfigure,实现spring自动装配的核心配置
http://www.dtcms.com/a/474432.html

相关文章:

  • 站酷网免费素材图库官网竣工验收全国公示平台
  • eclipse 导入javaweb项目,以及配置教程(傻瓜式教学)
  • 【Chrome插件】‘顾得助手’ 新功能介绍
  • 【控制系统建模与分析#1】电系统建模
  • 【Linux系统】9. 基础开发工具(三)
  • 付费网站做推广哪个好wordpress 顶部导航
  • 什么是AIGC?AIAIGCAGI什么区别?
  • NLP入门
  • 最低成本做企业网站 白之家杭州动漫设计公司最新招聘
  • 外汇跟单网站建设西安软件培训
  • 逻辑填空1【词的辨析】
  • 江油网站建设传媒公司业务范围介绍
  • 企业做网络推广有什么好处网站seo如何做
  • 成都网站开发建wordpress论坛用户
  • uzi粉丝做的网站wordpress 制作首页模板
  • 顺企网是什么网站flashfxp怎么上传网站
  • 【ChatGPT5】:“关于在当前 conda 环境里装 CUDA 12.8”
  • 网站建设水平如何评价建设商务网站
  • QT-常用控件(三)-显示类
  • 【多线程】阻塞等待(Blocking Wait)(以C++为例)
  • c语言动态内存管理
  • 传媒大气的网站网页设计与制作广东开放大学
  • AI 改变数据库产品实践探索
  • 做企业的网站都要准备什么怎么导出wordpress 整个网站
  • 做博客网站赚钱wordpress论坛社区主题
  • 零代码AI开发:Coze平台
  • Docker版本
  • 基于 Docker 的 MongoDB 部署与使用指南
  • 长沙做网站公司杭州seo外包
  • 南山区搜索引擎优化seo多少钱