Spring Boot自动装配、启动流程、配置优先级问题记录

 更新时间:2025年12月27日 14:11:16   作者:SpringHeather  
Spring Boot通过@EnableAutoConfiguration注解和条件注解,实现自动装配功能,但并非全自动,而是有条件,启动流程包括初始化SpringApplication实例和执行run()方法,本文介绍Spring Boot自动装配、启动流程、配置优先级问题记录,感兴趣的朋友跟随小编一起看看吧

问题 1:Spring Boot 自动装配的核心原理是什么?

Spring Boot 自动装配的核心依赖于 @EnableAutoConfiguration 注解(该注解被 @SpringBootApplication 组合注解包含,无需单独声明)。

核心流程:

  • 注解驱动:@EnableAutoConfiguration 通过 @Import(AutoConfigurationImportSelector.class) 导入核心选择器类;
  • 扫描配置:AutoConfigurationImportSelector 借助 SpringFactoriesLoader 工具,扫描项目所有依赖包下的 META-INF/spring.factories 文件(Spring Boot 2.x 版本),该文件中配置了大量自动配置类全路径(如 DataSourceAutoConfigurationWebMvcAutoConfiguration);
  • 条件筛选:自动配置类需满足预设条件才会生效,核心依赖 Spring 条件注解(如 @ConditionalOnClass 检查类路径是否存在指定类、@ConditionalOnMissingBean 检查用户是否自定义同类型 Bean、@ConditionalOnProperty 检查配置文件是否开启对应开关);
  • 配置生效:满足条件的自动配置类被 Spring 容器加载,完成 Bean 自动注册,实现“开箱即用”。

总结:Spring Boot 自动装配并非“全自动”,而是“有条件的自动装配”。核心是 @EnableAutoConfiguration 注解 + SpringFactoriesLoader 扫描机制 + 条件注解筛选的组合逻辑,既实现了简化配置,又保证了灵活可控。(注:Spring Boot 3.x 版本将自动配置类清单迁移至 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件,核心逻辑不变)

问题 2:Spring Boot 应用的完整启动流程(尤其是 Web 项目)

Spring Boot 的启动流程可以拆分为两个核心阶段:初始化 SpringApplication 实例执行 run() 方法

整个流程始终围绕三个核心目标展开:准备运行环境、创建并初始化应用上下文、启动核心业务逻辑

阶段一:执行 main 方法 & 初始化 SpringApplication

Spring Boot 应用的启动入口是 main 方法,核心调用为:

SpringApplication.run(Application.class, args);

在该调用中,首先会创建一个 SpringApplication 实例,并完成以下三件关键事情:

  1. 推断应用类型(Web / 非 Web / Reactive):通过检查类路径中是否存在 Servlet(Web 应用)、ReactiveWebApplicationContext(响应式应用)相关类来判定,决定后续创建的应用上下文类型;
  2. 加载初始化器与监听器:从 META-INF/spring.factories 中加载并实例化 ApplicationContextInitializer(应用上下文初始化器)和 ApplicationListener(应用事件监听器),这是后续自动装配和事件机制生效的关键前置步骤;
  3.  记录主启动类:定位并存储 main 方法所在的启动类,为后续 @ComponentScan 扫描配置类提供依据。

阶段二:执行 run() 方法(核心启动逻辑)

run() 方法是 Spring Boot 启动流程的核心入口,其内部按顺序完成以下五个关键步骤:

  • 准备运行环境(Environment):加载命令行参数、JVM 系统属性、环境变量、application.yml/properties 等配置来源,封装为 ConfigurableEnvironment 实例;并完成环境配置的校验与激活(如激活指定 Profile);
  •  创建应用上下文(ApplicationContext):根据阶段一推断的应用类型,创建对应类型的应用上下文(Web 应用默认创建AnnotationConfigServletWebServerApplicationContext);将阶段一准备的环境对象绑定到上下文;
  •  刷新应用上下文(refresh()):这是启动流程的核心步骤,完成 Bean 定义加载、Bean 实例化与依赖注入、事件监听器注册等工作;对于 Web 项目,此阶段会调用 createWebServer() 方法,通过 ServletWebServerFactory 工厂创建并启动嵌入式 Tomcat 服务器;
  •  执行启动后运行器(ApplicationRunner / CommandLineRunner):遍历 Spring 容器中所有实现这两个接口的 Bean,按顺序执行其 run() 方法,用于执行启动后的初始化任务(如加载基础数据、打印启动日志);两者区别:ApplicationRunner 接收解析后的 ApplicationArguments 对象,CommandLineRunner 接收原始命令行字符串数组;
  •  发布应用就绪事件(ApplicationReadyEvent):通过事件机制发布应用就绪事件,标识应用已完全启动,此时应用进入运行状态,可正常接收并处理外部请求。

问题 3:Spring Boot Web 项目如何启动嵌入式 Web 服务器?

答:Spring Boot Web 项目的嵌入式 Web 服务器(默认 Tomcat),核心是在 应用上下文刷新(refresh())阶段 启动,具体流程如下:

  • 依赖触发:项目引入 spring-boot-starter-web 依赖时,Spring Boot 会通过自动装配机制,加载 ServletWebServerFactoryAutoConfiguration 自动配置类;
  • 工厂创建:该自动配置类会根据类路径中的 Web 服务器依赖(如 Tomcat、Jetty),自动注册对应的 ServletWebServerFactory 工厂实例(默认注册 TomcatServletWebServerFactory);
  • 上下文绑定:阶段二创建应用上下文时,Web 应用会使用 AnnotationConfigServletWebServerApplicationContext,该上下文内置了 Web 服务器启动逻辑;
  • 服务器启动:在 refresh() 方法执行过程中,会调用 createWebServer() 方法,该方法通过 ServletWebServerFactory 工厂创建 TomcatWebServer 实例,内部调用 tomcat.start() 启动服务器;同时将项目中的 Servlet(如 DispatcherServlet)注册到服务器;
  • 就绪可用:服务器启动完成后,随应用就绪事件发布,开始监听指定端口(默认 8080),接收 HTTP 请求。

问题 4:Spring Boot 配置属性的优先级顺序

Spring Boot 支持多种外部配置来源,优先级明确(数字越小,优先级越高,后加载的配置会覆盖先加载的同名配置):

优先级

配置来源

示例

1

命令行参数

--server.port=8081

2

JVM 系统属性(-D 参数)

-Dserver.port=8082

3

操作系统环境变量

Windows:set SERVER_PORT=8083;Linux/Mac:export SERVER_PORT=8083

4

bootstrap.yml / bootstrap.properties(Spring Cloud 特有)

spring.application.name=cloud-demo

5

远程配置中心(如 Spring Cloud Config Server)

spring.datasource.url=jdbc:mysql://xxx:3306/db

6

激活的 Profile 配置文件(application-{profile}.yml / .properties)

application-prod.yml(需通过 spring.profiles.active=prod 激活)

7

默认全局配置(application.yml / application.properties)

application.yml 中配置 server.port=8080

8

@PropertySource 注解加载的自定义配置文件

@PropertySource("classpath:custom.properties")

9

应用代码中设置的默认值

SpringApplication.setDefaultProperties(Collections.singletonMap("server.port", 8084))

Profile 规则:激活的 Profile 配置文件优先级高于默认全局配置,即 application-{profile}.yml / .properties > application.yml / .properties;若同时激活多个 Profile,后激活的 Profile 配置会覆盖先激活的。

问题 5:application.yml 和 application.properties 哪个优先级更高?

答:在 Spring Boot 中,application.ymlapplication.properties 属于同一优先级层级,当两者并存且存在同名配置时,后被 Spring 加载的配置会覆盖先加载的

默认加载顺序:Spring Boot 会先加载 application.properties,再加载 application.yml,因此同名配置最终生效的是application.yml 的配置;但该顺序可通过自定义配置加载逻辑修改,核心原则是“同层级配置,后加载覆盖先加载”。

注意:若两者与 Profile 结合(如 application-prod.yml 和 application-prod.properties),规则相同——同一 Profile 下的 properties 和 yml 同优先级,后加载者覆盖先加载者。

问题 6:Spring Cloud 中的 bootstrap.yml 是什么?和 application.yml 有何区别?

答:

核心特性:bootstrap.yml 是 Spring Cloud 生态特有的启动级配置文件,基于 Spring Cloud 的“引导上下文(Bootstrap Context)”机制加载。引导上下文是应用主上下文的父上下文,优先级更高,主要用于加载应用启动过程中“必须提前准备的核心配置”(如远程配置中心地址、服务注册中心地址、应用名称等),确保这些配置在主上下文初始化前就绪。

与 application.yml 区别

特性

bootstrap.yml

application.yml

加载时机

引导上下文初始化前(应用启动最早期)

应用主上下文初始化时

依赖机制

依赖 Spring Cloud 引导机制,无 Spring Cloud 依赖时不生效

Spring Boot 原生支持,无需额外依赖

典型用途

1. 配置远程配置中心地址(spring.cloud.config.uri);2. 配置服务注册中心地址(eureka.client.serviceUrl.defaultZone);3. 定义应用名称(spring.application.name,用于服务发现和配置中心定位);4. 配置加密/解密密钥(用于解密配置中心的敏感配置)

1. 应用端口(server.port);2. 数据库连接信息(spring.datasource.*);3. 日志配置(logging.*);4. 业务自定义属性(如 user.name)

优先级

更高(覆盖同名的 application.yml 配置)

更低(被 bootstrap.yml 同名配置覆盖)

Profile 支持

支持 bootstrap-{profile}.yml,优先级:bootstrap-{profile}.yml > bootstrap.yml

支持 application-{profile}.yml,优先级:application-{profile}.yml > application.yml

到此这篇关于Spring Boot自动装配、启动流程、配置优先级问题记录的文章就介绍到这了,更多相关Spring Boot自动装配 启动流程 配置优先级内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • idea找不到xxx依赖项的问题及解决方法

    idea找不到xxx依赖项的问题及解决方法

    今天下载这个依赖一直报错,红色,显示错误找不到依赖项,使用了3个步骤,不太明白哪部解决的,下面小编给大家分享idea找不到xxx依赖项的问题及解决方法,感兴趣的朋友跟随小编一起看看吧
    2024-06-06
  • Eclipse引用XSD实现XML配置文件提示标签的方法

    Eclipse引用XSD实现XML配置文件提示标签的方法

    今天小编就为大家分享一篇关于Eclipse引用XSD实现XML配置文件提示标签的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • 浅析我对 String、StringBuilder、StringBuffer 的理解

    浅析我对 String、StringBuilder、StringBuffer 的理解

    StringBuilder、StringBuffer 和 String 一样,都是用于存储字符串的。这篇文章谈谈小编对String、StringBuilder、StringBuffer 的理解,感兴趣的朋友跟随小编一起看看吧
    2020-05-05
  • 微信随机生成红包金额算法java版

    微信随机生成红包金额算法java版

    这篇文章主要为大家详细介绍了java和php版的微信随机生成红包金额算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-07-07
  • Java阻塞延迟队列DelayQueue原理及使用详解

    Java阻塞延迟队列DelayQueue原理及使用详解

    这篇文章主要介绍了Java阻塞延迟队列DelayQueue原理及使用详解,阻塞队列是一个支持两个附加操作的队列,这两个附加的操作是:在队列为空时,从队列中获取元素的消费者线程会一直等待直到队列变为非空,需要的朋友可以参考下
    2023-12-12
  • logback日志级别设置无效问题及解决

    logback日志级别设置无效问题及解决

    文章总结:文章介绍了在Spring Boot项目中配置日志级别时,优先级问题,通过查阅资料发现,配置文件中的logging.level.xx也能配置日志级别,且优先级比logback.xml高,文章还提供了源码分析,说明了Spring Boot如何处理日志级别配置
    2025-11-11
  • Mybatis-plus通过添加拦截器实现简单数据权限

    Mybatis-plus通过添加拦截器实现简单数据权限

    系统需要根据用户所属的公司,来做一下数据权限控制,具体一点,就是通过表中的company_id进行权限控制,项目使用的是mybatis-plus,所以通过添加拦截器的方式,修改查询sql,实现数据权限,本文就通过代码给大家详细的讲解一下,需要的朋友可以参考下
    2023-08-08
  • 你的Idea还有BUG吗不妨试试另一个开发神器

    你的Idea还有BUG吗不妨试试另一个开发神器

    Spring Tool Suite(STS)就是一个基于Eclipse的开发环境, 用于开发Spring应用程序。本文给大家给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2020-12-12
  • 详解Java8新特性之interface中的static方法和default方法

    详解Java8新特性之interface中的static方法和default方法

    这篇文章主要介绍了Java8新特性之interface中的static方法和default方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-08-08
  • 解决JTable排序问题的方法详解

    解决JTable排序问题的方法详解

    本篇文章是对JTable排序问题的方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05

最新评论