锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. Spring Boot 自动配置原理及过程

Spring Boot 自动配置原理及过程

0
  • 软件开发
  • 发布于 2024-08-16
  • 0 次阅读
黄健
黄健

本文由 简悦 SimpRead 转码, 原文地址 blog.csdn.net

Spring Boot 是一个基于 Spring 框架的快速应用开发框架,它极大地简化了开发流程,使得开发者能够更加快速地构建应用程序。Spring Boot 中的一个关键特性就是自动配置(Auto-Configuration),这使得开发者无需手动编写大量的配置代码就能得到一个功能完善的 Spring 应用程序。

1. 基本原理

Spring Boot 的自动配置是基于 Spring 框架的核心功能——依赖注入(Dependency Injection)和自动装配(Bean Auto-Wiring)。

1.1. 启动类和 @SpringBootApplication 注解

启动类:Spring Boot 应用通常有一个主类,这个主类上会有一个 @SpringBootApplication 注解。

@SpringBootApplication 注解:该注解是一个组合注解

  • @SpringBootConfiguration:表示这是一个 Spring 配置类。
  • @EnableAutoConfiguration:启用自动配置功能,告诉 Spring Boot 启动自动配置。
  • @ComponentScan:扫描指定包下的组件,以便于发现并装配带有 @Component、@Service、@Repository 或 @Controller 等注解的类。

1.2.@EnableAutoConfiguration 注解

@EnableAutoConfiguration注解:该注解本身也是一个组合注解

  • @AutoConfigurationPackage:这个注解会告诉 Spring Boot 扫描当前包以及子包中的 @Component 相关的注解。
  • @Import({AutoConfigurationImportSelector.class})
    • AutoConfigurationImportSelector 类:通过这个类,Spring Boot 会在启动时选择并导入一组自动配置类。

1.3. 自动配置类的发现

  • AutoConfigurationImportSelector 类:在 Spring 容器启动过程中,这个类会从 META-INF/spring.factories 文件中读取所有候选的自动配置类。

  • spring.factories 文件:位于每个自动配置模块的 META-INF 目录下,包含了一系列的自动配置类和它们对应的条件,每个类都是一个配置项。

  • org.springframework.boot.autoconfigure.AutoConfiguration.imports

    在 src/main/resources/META-INF/spring 文件夹下的org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件功能与 spring.factories一样。都是用来加载自动装配的类。

    两者目的都是为引入外部的 jar,把外部 bean 纳入到 Spring 容器,实现外部组件与 Spring 的集成, 主要区别当前方式通过配置的信息创建内部是具体的要导入到 Spring 环境的中的配置类, 而spring.factories这种方式,内部是 key-value 的形式。

    注意:从 spring boot2.7 开始,慢慢不支持META-INF/spring.factories文件了需要导入的自动配置类可以放在
    /META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中。

1.4. 条件匹配

  • @Conditional 注解:自动配置类中的每个 Bean 都可能带有 @Conditional 注解,它用来指定配置类生效的条件。

  • 条件注解:例如 @ConditionalOnClass、@ConditionalOnMissingClass、@ConditionalOnBean、@ConditionalOnMissingBean 等,这些注解可以帮助决定哪些自动配置类会被激活。

    @ConditionalOnClass: 当指定的类位于类路径上时,才会启用被注解的组件或配置。这可用于根据类的可用性来决定是否启用某个特定功能。
    @ConditionalOnMissingClass: 当指定的类不在类路径上时,才会启用被注解的组件或配置。这可用于在某些类不可用时应用备用实现。
    @ConditionalOnBean: 当指定的 Bean 在应用程序上下文中存在时,才会启用被注解的组件或配置。这可以用于基于其他 Bean 的存在与否来决定是否启用特定功能。
    @ConditionalOnMissingBean : 当指定的 Bean 在应用程序上下文中不存在时,才会启用被注解的组件或配置。这可用于提供默认实现或避免重复创建 Bean。
    @ConditionalOnProperty: 当指定的属性满足条件时, 才会启用被注解的组件或配置。这可用于基于配置属性的值来决定是否启用特定功能。
    @ConditionalOnExpression: 当指定的 SpEL 表达式计算结果为 true 时,才会启用被注解的组件或配置。这可用于更复杂的条件判断。

1.5. 自动配置类

  • 自动配置类:每个自动配置类通常会针对一个特定的框架或技术栈(如 Tomcat、JPA、Redis 等)。
  • 配置 Bean:自动配置类内部会通过 @Bean 方法来注册 Bean 到 Spring 容器中。
  • 属性绑定:自动配置类还可以通过 @ConfigurationProperties 注解来绑定配置文件中的属性到特定的 Java 对象上。

1.6. 配置文件

  • application.properties 或 application.yml:这些文件包含了 Spring Boot 应用程序的配置信息,用于调整自动配置的行为。

1.7.Starter 依赖

Spring Boot 提供了一组 “starter” 依赖,这些依赖简化了项目的依赖管理。每个 starter 包含了构建典型应用所需的依赖项,而无需编写复杂的 XML 配置文件。例如,spring-boot-starter-web 包含了 Web 应用所需的所有依赖,如 Spring MVC、Tomcat(默认的嵌入式容器)等。

2. 自动装配的过程

2.1 启动 Spring 应用

当你运行带有 @SpringBootApplication 注解的主类时,Spring Boot 会开始初始化 Spring 应用上下文。

2.2 导入自动配置

  • @EnableAutoConfiguration:该注解触发了 AutoConfigurationImportSelector 的执行。
  • AutoConfigurationImportSelector:这个类会根据类路径上的可用资源来决定应该导入哪些自动配置类。
  • 选择自动配置类:通过 getCandidateConfigurations() 方法,AutoConfigurationImportSelector 会读取 spring.factories 文件中的配置,从中挑选出所有以 org.springframework.boot.autoconfigure. 开头的配置类。

2.3 加载自动配置类

  • 加载配置类:Spring 会将这些自动配置类加载到应用上下文中。
  • 解析条件注解:对于每个自动配置类,Spring 会检查 @Conditional 注解来确定是否应该激活该配置类。
  • 条件匹配:如果条件匹配成功,则会创建配置类的实例,并执行其 @Bean 方法来注册 Bean。

2.4 注册 Bean

  • 注册 Bean:自动配置类中的 @Bean 方法会被执行,这些方法会创建并注册新的 Bean 到 Spring 容器中。
  • 属性绑定:如果有 @ConfigurationProperties 注解,则会尝试从配置文件中读取相应的属性值并绑定到相应的 Java 对象上。

2.5 应用配置

  • 最终配置:所有的自动配置完成后,Spring Boot 会将所有注册的 Bean 进行依赖注入,从而完成整个应用的初始化过程。

3. 示例 :MyBatis

当使用 MyBatis 作为持久层框架时,Spring Boot 会自动配置 MyBatis 相关的组件,以简化 MyBatis 的集成。

3.1. 添加依赖

在 pom.xml 文件中添加 MyBatis 和 Spring Boot Starter MyBatis 的 Starter 依赖:

mybatis-spring-boot-starter,它会自动添加 MyBatis 和其他相关依赖,而不需要你显式声明每一个依赖。

<!-- Maven -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.1</version>
</dependency>

3.2. 启动类

在启动类上 @SpringBootApplication 注解包含 @EnableAutoConfiguration 启动自动装配

3.3. 自动配置的发现

  • @EnableAutoConfiguration:这个注解告诉 Spring Boot 启动自动配置过程。

  • AutoConfigurationImportSelector:这个类负责从 spring.factories 文件中读取所有候选的自动配置类。该文件列出了所有候选的自动配置类。

    # META-INF/spring.factories
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
        org.springframework.boot.autoconfigure.admin.SpringApplicationAdminAutoConfiguration,\ 
        org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ 
        org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\ 
        ...,
        org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration
    
  • spring.factories 文件:位于 META-INF 目录下,包含了 MyBatis 相关的自动配置类,如 org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration。

3.4. 自动配置类

  • MybatisAutoConfiguration:这个类是 Spring Boot 为 MyBatis 提供的自动配置类,它负责配置 MyBatis 的核心组件。

  • 条件注解:该类中的 @Bean 方法通常带有 @Conditional 注解,用来控制自动配置的条件。类上的@ConditionalOnClass 来确认 MyBatis 类的存在,或者使用 @ConditionalOnMissingBean 来避免重复配置。

    @Configuration
    @ConditionalOnClass({ SqlSessionFactory.class })
    @EnableConfigurationProperties(MybatisProperties.class)
    @AutoConfigureBefore({ DataSourceAutoConfiguration.class, TransactionManagementAutoConfiguration.class })
    public class MybatisAutoConfiguration {
        // ...
    }
    

3.5. 属性绑定

类上的@EnableConfigurationProperties(MybatisProperties.class)注解用来读取配置信息

@ConfigurationProperties(
    prefix = "mybatis"
)
public class MybatisProperties {
    ...
}

通过 @ConfigurationProperties 从自 application.properties 或 application.yml 的配置文件中读取 mybatis.mapper-locations配置信息

3.6. 自动配置顺序 @AutoConfigureAfter

@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})

MybatisAutoConfiguration它依赖于 DataSourceAutoConfiguration 和 MybatisLanguageDriverAutoConfiguration 两个功能, 通过这个注解确保 MybatisAutoConfiguration 在这两个自动配置类之后被加载,以确保 MyBatis 可以正确地使用数据源和语言驱动配置。

其中 DataSourceAutoConfiguration

@AutoConfiguration(
    before = {SqlInitializationAutoConfiguration.class}
)
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
@ConditionalOnMissingBean(
    type = {"io.r2dbc.spi.ConnectionFactory"}
)
@EnableConfigurationProperties({DataSourceProperties.class})
@Import({DataSourcePoolMetadataProvidersConfiguration.class, DataSourceCheckpointRestoreConfiguration.class})
public class DataSourceAutoConfiguration {
	...
}

通过 DataSourceProperties

@ConfigurationProperties(
    prefix = "spring.datasource"
)
public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {
	
    ...
    
    private String driverClassName;
    private String url;
    private String username;
    private String password;
    ...
}

读取 spring.datasource.url、spring.datasource.username 和 spring.datasource.password,绑定到 MybatisProperties 对象上 Spring Boot 就会自动创建一个数据库连接池。

3.7. 注册 Bean

自动配置类通过 @Bean 方法来注册各种 Bean。例如,MybatisAutoConfiguration 会注册 SqlSessionFactory、SqlSessionTemplate 和 MapperScannerConfigurer 等 Bean。

  • DataSource:如果未显式配置 DataSource,Spring Boot 会自动创建一个 DataSource 实例。

  • SqlSessionFactory:MybatisAutoConfiguration 会创建 SqlSessionFactory,这是 MyBatis 的核心组件。

  • MapperScannerConfigurer:用于扫描带有 @Mapper 注解的接口,自动生成对应的 Mapper Bean。

  • TransactionManager:如果使用了 JTA 或 DataSource 事务管理器,MybatisAutoConfiguration 也会配置事务管理器。

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({MybatisProperties.class})
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})
public class MybatisAutoConfiguration implements InitializingBean {

    private final MybatisProperties properties;
    private final DataSource dataSource;

    public MybatisAutoConfiguration(DataSource dataSource, MybatisProperties properties) {
        this.dataSource = dataSource;
        this.properties = properties;
    }

    @Bean
    @ConditionalOnMissingBean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(dataSource);
        factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
        // 更多配置...
        return factory.getObject();
    }

    @Bean
    @ConditionalOnMissingBean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnClass({ MapperFactoryBean.class, MapperScannerConfigurer.class })
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        mapperScannerConfigurer.setBasePackage(this.properties.getMapperLocations());
        // 更多配置...
        return mapperScannerConfigurer;
    }
}

3.8. 应用配置

最终配置:所有的自动配置完成后,Spring Boot 会将所有注册的 Bean 进行依赖注入,从而完成整个应用的初始化过程。

4. 总结

Spring Boot 的自动配置过程主要包括以下几个步骤:

  • 通过 @SpringBootApplication 注解启动自动配置。
  • 通过 AutoConfigurationImportSelector 选择并导入自动配置类。
  • 根据条件注解来确定哪些配置类应该被激活。
  • 通过 @Bean 方法注册 Bean 到 Spring 容器中。
  • 通过 @ConfigurationProperties 绑定配置文件中的属性到 Java 对象上。

通过这种方式,Spring Boot 大大简化了设置和配置 Spring 应用的过程,让开发者能够专注于业务逻辑而不是基础设施配置。

标签: #Spring Boot 173 #软件开发 1171 #JAVA 991
相关文章

万字:支付“核心系统”详解 2024-11-02 15:33

专栏作者:隐墨星辰 \| 主编:陈天宇宙 这篇文章也尝试化繁为简,探寻支付系统的本质,讲清楚在线支付系统最核心的一些概念和设计理念。 虽然支付行业已经过了风头最劲的时光,但跨境支付仍然在蓬勃发展,每年依然有很多新人进入这个行业,这篇文章尝试为这些刚入行的新人提供一点帮助。 文章只介绍一些支付行业十几

资深支付架构师视角:实战从问题定义到代码落地的完整套路 2024-11-02 15:33

前言 今天从一个实际案例入手,介绍站在架构师的角度,如何识别并定义问题,提炼需求,技术方案选型,再到详细设计,最后利用AI的能力协助写出核心的代码,验证与调优。 解决问题存在一定的模式,也可以称之为框架,总结出自己的思考和解题框架,以后再碰到同类型的问题就可以如庖丁解牛一样容易。 很多年前,我写代码

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

设计模式第16讲——迭代器模式(Iterator) 2024-10-08 11:24

一、什么是迭代器模式 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。 二、角色组成 抽象迭代器(Iterator):定义了遍历聚合对象所需的方法

vue2路由和vue3路由区别及原理 2024-10-08 11:24

一、Vue2 与 Vue3 路由的区别 1. 创建路由实例方式的不同 Vue 2 中,通过 Vue.use() 注册路由插件,并通过 new VueRouter() 来创建路由实例。 import Vue from 'vue';import VueRouter from 'vue-router';i

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.