Spring Boot 自动配置原理:从启动到生产,框架替你做了什么 从“Hello World”到“启动即生产”Spring Boot 到底替你做了哪些事如果你写过几年 Java Web应该还记得 2015 年前后搭一个 SSMSpring Spring MVC MyBatis项目的痛苦web.xml要配置监听器、过滤器、DispatcherServletSpring 配置文件里要写组件扫描、数据源、事务管理器、MyBatis 的 MapperScannerConfigurer还得手动把 Tomcat 装到开发机、配置 server.xml最后用 IDEA 的 Artifacts 打 war 包扔进 webapps。一套流程走下来新手至少折腾半天老手也免不了在依赖版本上翻车。Spring Boot 出现之后这个局面被彻底改掉了。它最核心的贡献不是发明了什么分布式新理论也不是取代了 Spring Framework而是把“从零搭一个能跑起来的 Web 项目”这件事从以小时计、以天计压缩到了分钟级。你只需要一个main方法加一个注解项目就能以可执行 Jar 的方式跑起来。这篇文章是这个系列的第一节重点不是教你怎么写出一个复杂的微服务而是回答三个问题Spring Boot 到底是什么它和传统 Spring 项目的本质区别在哪里它真正帮你做了哪些事哪些事又必须由你自己负责把这些底层逻辑理清楚后面学自动装配、starter 机制、配置体系、整合各种中间件时你才能不是“照着抄”而是“看得懂”。1. 这篇文章真正要解决的问题先说一个很常见的现象。很多初学者在 IDEA 里通过 Spring Initializr 创建项目勾选几个依赖点击运行看到Tomcat started on port(s): 8080之后就觉得“Spring Boot 我会了”。但一旦遇到下面的问题就开始懵为什么我加了一个SpringBootApplication项目就能自动扫描到 Controller为什么我引入了spring-boot-starter-data-redis什么都不配就能拿到RedisTemplate为什么我把项目从 Spring Boot 2.x 升到 3.x启动直接报 ClassNotFoundException为什么别人的application.yml有提示我的却没有为什么同一个依赖在普通 Maven 项目里能编译在 Spring Boot 里就冲突这些问题看似零散背后其实是同一个根源你不清楚 Spring Boot 的“自动配置”到底在什么时候、根据什么条件、加载了哪些类。这篇文章要解决的就是帮你建立对 Spring Boot 的整体认知框架。它不是一份 API 手册而是帮你把“Spring Boot 是什么、做了什么、边界在哪里”这三个问题讲透。读完你至少应该能回答Spring Boot 与 Spring Framework 的关系是什么SpringBootApplication这一个注解为什么能顶替以前一整套 XML 配置自动装配的触发机制是什么为什么有的配置类生效、有的不生效一个 Spring Boot 项目从启动到对外提供服务中间经历了哪几个关键阶段实际项目中哪些坑是 Spring Boot 最常见的如何提前规避如果你正准备面试、刚转 Java 后端、或者用了 Spring Boot 两年但一直停留在“会用”层面这篇文章适合你。2. Spring Boot 的核心定位不是框架是“开发体验整合层”很多人把 Spring Boot 称作“框架”这在口语上没问题但容易造成误解。准确地说Spring Boot 本身并没有提出一套新的 Web 开发模型也没有替代 Spring MVC、Spring JDBC 这些底层模块。它是在 Spring Framework 之上做了一层面向开发者的“整合与自动化”封装。可以把它理解为“精装修交付”和“毛坯房”的区别。传统 Spring 项目给你的是毛坯房墙体结构都在但水电、地板、橱柜都得你自己找人做。Spring Boot 则是精装修样板间你选好户型starter它把水电管线、开关插座、基础家具都按默认标准装好了你只需要搬进去放上自己的东西。Spring Boot 真正做的几件事可以归纳为依赖管理通过spring-boot-starter-*系列把一组兼容的依赖打包提供减少版本冲突。自动配置通过条件注解在项目启动时根据 classpath、配置项、已有 Bean 等情况自动装配常见组件。内嵌服务器内置 Tomcat、Jetty 或 Undertow项目以可执行 Jar 方式运行不再需要外部部署 war 包。生产就绪特性提供 Actuator 监控端点、健康检查、外部化配置等能力。约定优于配置提供一套默认约定比如静态资源位置、配置文件名、Bean 扫描根包等大多数情况下不需要显式声明。但要注意Spring Boot 并没有消灭配置而是把“必须由你写的配置”压缩到了最小把“可以按默认值运行的配置”自动化了。如果你有特殊需求依然可以通过application.yml、自定义Bean、ConfigurationProperties等方式覆盖默认行为。从工程管理角度看Spring Boot 改变的是项目的“最低启动成本”。过去启动一个 Web 项目你需要同时理解 Servlet 规范、Spring 容器初始化流程、Web 描述符、构建工具等多个知识点。现在你只需要一个启动类剩下的事情交给 Boot。这意味着 Java 后端开发的学习曲线被显著拉平了但也带来了一个副作用很多人会用了却不理解底层出了问题无从排查。3. 自动装配原理SpringBootApplication 背后发生了什么如果只能选一个 Spring Boot 最核心的机制毫无疑问是“自动装配”Auto Configuration。这一节我们从浅到深拆开看。3.1 SpringBootApplication 组合注解先看最常见的启动类代码// 文件路径src/main/java/com/example/demo/DemoApplication.java package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }SpringBootApplication是一个组合注解它同时包含了三个核心注解SpringBootConfiguration本质是Configuration表示当前类是一个配置类允许通过Bean方法注册 Bean。EnableAutoConfiguration开启 Spring Boot 的自动配置机制这是最核心的一个。ComponentScan默认扫描启动类所在包及其子包把带有Component、Service、Controller、Repository等注解的类注册为 Bean。很多初学者会问为什么 Controller 放在启动类的子包里就能被扫描到放在包外面就不行答案就在这里。ComponentScan默认的 basePackage 就是启动类所在包。如果你的 Controller 不在这个包及子包下Spring 容器根本看不见它。3.2 auto-configuration 的加载机制EnableAutoConfiguration并不是真的把所有自动配置类全量加载——那样既慢又容易冲突。它的真正逻辑是通过 Spring SPI 机制从 classpath 下读取自动配置类的候选列表。遍历这些候选类通过Conditional系列注解判断是否满足条件。满足条件的配置类才会被加载并注册相关 Bean。在 Spring Boot 2.7 之后自动配置类的候选清单文件路径是META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports在更早的 2.x 版本中路径是META-INF/spring.factoriesSpring Boot 自带的各种自动配置类比如DataSourceAutoConfiguration、RedisAutoConfiguration、WebMvcAutoConfiguration都在这些文件里声明。判断条件则主要由条件注解完成常见的包括ConditionalOnClassclasspath 中存在某个类时才生效。ConditionalOnMissingBean容器中不存在某个 Bean 时才生效。ConditionalOnProperty指定的配置项满足值时才生效。ConditionalOnWebApplication当前应用是 Web 应用时才生效。举个例子。你引入了spring-boot-starter-data-redisclasspath 中出现了RedisTemplate相关的类RedisAutoConfiguration就会生效并自动注册一个使用默认连接工厂的RedisTemplateBean。如果你的项目里已经手动定义了一个RedisTemplateConditionalOnMissingBean会阻止自动配置覆盖你的实现。这里需要牢记一个原则自动配置的优先级低于用户自定义 Bean。当你对默认行为不满意时优先用显式声明覆盖而不是改 Spring Boot 的自动配置类。3.3 一个最小的自定义条件装配示例为了验证上面的原理我们可以写一个非常小的配置类模拟条件判断// 文件路径src/main/java/com/example/demo/config/FeatureConfig.java package com.example.demo.config; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class FeatureConfig { Bean ConditionalOnProperty(name demo.feature.enabled, havingValue true) public FeatureService featureService() { return new FeatureService(); } static class FeatureService { public String hello() { return feature is enabled; } } }当你在application.yml中配置demo: feature: enabled: true启动后FeatureService才会被注册到容器。如果配置缺失或值不为true这个 Bean 不会创建。这就是自动配置中的条件判断逻辑的简化版。理解了这一段你就明白了为什么 Spring Boot 的配置类“有的生效、有的不生效”。4. Spring Boot 帮你做完了哪些事从启动到服务可用的完整路径我们要想真正理解 Spring Boot最好把它从启动到服务可用的完整路径拆开看一遍。一个 Spring Boot 应用启动时核心入口是SpringApplication.run(DemoApplication.class, args)。这个方法的执行大致可分为几个阶段确定应用类型根据 classpath 判断是 Web 应用、响应式 Web 应用还是普通应用。加载ApplicationContextInitializer和ApplicationListener这些组件通过 SPI 机制加载用于后续定制容器和监听事件。准备环境变量Environment读取配置文件、系统属性、环境变量等形成统一的配置来源。创建 ApplicationContext针对不同类型应用创建对应的容器实现比如AnnotationConfigServletWebServerApplicationContext。执行自动装配在容器刷新过程中执行EnableAutoConfiguration导入的自动配置类。刷新容器完成 Bean 的创建、依赖注入、初始化等。启动内嵌 Web 服务器如果检测到 Web 环境启动 Tomcat/Jetty/Undertow 并绑定端口。发布ApplicationReadyEvent表示应用已经准备就绪。用一句话概括Spring Boot 把传统 Spring 项目中的“创建容器、加载配置、扫描 Bean、初始化服务器、发布事件”这些步骤全部自动化了。为了直观我们可以看一段标准启动日志. ____ _ __ _ _ /\\ / ____ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | _ | _| | _ \/ _ | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) |____| .__|_| |_|_| |_\__, | / / / / |_||___//_/_/_/ :: Spring Boot :: (v2.7.18) 2024-01-15 10:00:00.001 INFO 12345 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication ... 2024-01-15 10:00:00.200 INFO 12345 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to 1 default profile: default 2024-01-15 10:00:01.500 INFO 12345 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2024-01-15 10:00:01.800 INFO 12345 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2024-01-15 10:00:02.100 INFO 12345 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path 2024-01-15 10:00:02.200 INFO 12345 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 2.3 seconds注意日志里的变化Tomcat started on port(s): 8080这说明内嵌 Tomcat 已经被启动。在传统项目中这一步通常需要你手动安装 Tomcat、配置server.xml、把项目打成 war 包部署到webapps目录。在 Spring Boot 中这一切都隐藏在了启动流程里。如果启动失败最快的排查方式是先看日志中是否出现APPLICATION FAILED TO START字样。Spring Boot 的失败分析器会给出比较友好的提示比如端口冲突、Bean 命名冲突、自动配置失败原因等。不要直接去搜异常堆栈的最后一行先看失败分析器给出的 Summary。5. 最小可运行应用与代码示例前面讲了原理这一节进入实操。我们将从零创建一个最简单但完整的 Spring Boot Web 应用。5.1 环境准备与前置条件本文不绑定具体的操作系统但建议开发环境满足JDK版本以你选择的 Spring Boot 大版本为准。如果你使用 Spring Boot 2.7.xJDK 8 或 11 都可以如果使用 Spring Boot 3.x需要 JDK 17 及以上。Maven3.6 或以上版本。IDEIDEA 或 Eclipse 均可。IDEA Community 版也支持创建和运行 Spring Boot 项目。版本号是一个需要注意的地方。Spring Boot 2.x 的最终版本是 2.7.xSpring Boot 3.x 是目前的主流大版本4.0 也在推进中。选版本时不要盲目追求最新要结合你的 JDK 版本、团队技术栈和第三方依赖兼容性。如果公司项目还在 JDK 8就不要强行上 Spring Boot 3.x否则会遇到大量第三方库不兼容的问题。5.2 创建 Maven 项目在 IDEA 中可以直接通过 Spring Initializr 创建这里展示等价的 Maven 配置。!-- 文件路径pom.xml -- ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.7.18/version relativePath/ /parent groupIdcom.example/groupId artifactIddemo/artifactId version0.0.1-SNAPSHOT/version namedemo/name descriptionSpring Boot demo project/description properties java.version1.8/java.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin /plugins /build /project这里的spring-boot-starter-parent是一个非常关键的父 POM。它帮你做了依赖版本管理你引入的大多数spring-boot-starter-*都不需要显式写version版本由父 POM 统一管理。这是很多新手疑惑的地方为什么别人的 pom 里 starter 不写版本原因就在这里。5.3 编写启动类和 Controller创建启动类// 文件路径src/main/java/com/example/demo/DemoApplication.java package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }创建测试接口// 文件路径src/main/java/com/example/demo/controller/HelloController.java package com.example.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; RestController public class HelloController { GetMapping(/hello) public String hello() { return Hello, Spring Boot!; } }RestController是Controller和ResponseBody的组合表示这个类中的处理方法返回值会直接写入 HTTP 响应体不需要再走视图解析器。这也是 Spring Boot 项目普遍采用 REST 接口风格的原因之一。5.4 运行与验证在 IDEA 中直接运行DemoApplication的main方法或者在项目根目录执行mvn spring-boot:run启动成功后访问http://localhost:8080/hello浏览器或 curl 会返回Hello, Spring Boot!如果要用curl验证curl http://localhost:8080/hello预期输出为Hello, Spring Boot!。这个最小示例把前面讲的自动配置、内嵌 Tomcat、组件扫描全部串起来了。你没有配置任何 Servlet没有配置 Spring MVC 的 DispatcherServlet没有配置 Tomcat但项目就是能跑起来。放到传统 SSM 项目里这几乎是不可思议的。6. 配置体系约定优于配置的落地Spring Boot 的默认配置几乎覆盖了所有常规场景但真实项目一定会有定制需求。这一节讲配置文件的核心用法。6.1 配置文件格式与位置Spring Boot 默认支持application.properties和application.yml两种格式。推荐使用 YAML因为它结构清晰、支持层级关系。# 文件路径src/main/resources/application.yml server: port: 8080 servlet: context-path: /demo spring: application: name: demo-service对应的application.properties写法server.port8080 server.servlet.context-path/demo spring.application.namedemo-service两种格式等价不要在同一目录下同时使用两个同名文件避免出现预期外的加载顺序问题。Spring Boot 的加载顺序是先读取application.properties再读取application.yml后读取的会覆盖先读取的配置项。6.2 多环境配置实际项目中通常要区分开发、测试、生产环境。推荐做法是将公共配置放在application.yml环境相关配置放在application-dev.yml、application-test.yml、application-prod.yml中。# 文件路径src/main/resources/application-dev.yml server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/dev_db username: root password: 123456# 文件路径src/main/resources/application-prod.yml server: port: 8080 spring: datasource: url: jdbc:mysql://prod-server:3306/prod_db username: prod_user password: ${DB_PASSWORD}通过启动参数指定环境java -jar demo.jar --spring.profiles.activeprod也可以通过环境变量指定export SPRING_PROFILES_ACTIVEprod java -jar demo.jar生产环境不要把数据库密码明文写在配置文件里建议通过环境变量或配置中心注入。在application-prod.yml中写${DB_PASSWORD}就是让 Spring Boot 从环境变量中读取值。6.3 配置项映射到 Java 对象当配置项较多时不要用散落的Value注解而应该用ConfigurationProperties绑定到一个配置类便于集中管理和类型安全校验。# 文件路径src/main/resources/application.yml app: upload: path: /data/upload max-size: 10485760// 文件路径src/main/java/com/example/demo/config/UploadProperties.java package com.example.demo.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; Component ConfigurationProperties(prefix app.upload) public class UploadProperties { private String path; private long maxSize; public String getPath() { return path; } public void setPath(String path) { this.path path; } public long getMaxSize() { return maxSize; } public void setMaxSize(long maxSize) { this.maxSize maxSize; } }之后在任意 Bean 中直接注入UploadProperties即可。这里有一个值得背下来的配置优先级顺序从高到低命令行参数Java 系统属性System.getProperties()操作系统环境变量application-{profile}.ymlapplication.ymlSpring Boot 自动配置的默认值理解了这个顺序很多“我改了配置为什么没生效”的问题就能自我排查了。最常见的情况是IDEA 的运行配置里加了环境变量覆盖了application.yml中的值而你没意识到。7. Spring Boot 的常见误区与面试高频问题第一节内容比较基础但下面这些误区值得提前指出因为它们直接关系到后续学习。7.1 误区一Spring Boot 是新一代 Java Web 框架严格说Spring Boot 不是一个全新的 Web 框架Web 层依然由 Spring MVC 处理业务层依然基于 Spring 的 IOC 和 AOP。Spring Boot 做的是把 Spring 的配置过程自动化。面试时如果被问到建议这样回答Spring Boot 是 Spring Framework 之上的快速开发脚手架它利用自动配置和 starter 机制降低了 Spring 项目的搭建与运维成本底层依然运行在 Spring 容器之上。7.2 误区二Spring Boot 项目不需要配置文件常见于小 demo但生产项目不现实。数据库连接、缓存连接、消息队列、线程池、日志级别、超时时间这些都是需要配置的。Spring Boot 的意义是把基础设施的默认值做好让开发者在没有特殊需求时少写代码但不代表配置不存在。7.3 误区三自动配置越全越好自动配置虽然方便但也有代价加载了不需要的组件增加启动时间甚至引入潜在冲突。实际优化时可以用exclude关闭不需要的自动配置spring.autoconfigure.excludeorg.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration或者显式排除spring: autoconfigure: exclude: - org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration当然只在你确定不需要某个自动配置时再做这个操作。盲目排除会导致依赖的 Bean 缺失项目根本无法启动。7.4 一个高频面试题Spring Boot 与 Spring Cloud 的关系Spring Boot 主要解决的是“单个应用的开发与运行问题”Spring Cloud 则是在 Spring Boot 基础上提供了一组分布式系统开发工具比如服务注册发现、配置中心、网关、熔断器等。可以理解为Spring Boot 解决“应用怎么快速跑起来”Spring Cloud 解决“一堆应用怎么协同工作”。通常先掌握 Spring Boot再学习 Spring Cloud。这个问题的另一个理解角度是Spring Cloud 的各个组件本身就是基于 Spring Boot 的自动配置机制实现的服务启动后自动注册到 Nacos 或 Eureka靠的也是 Starter 和自动配置。所以如果不理解 Spring Boot 的自动装配Spring Cloud 学起来会非常吃力。8. 运行结果、效果验证与常见问题排查8.1 验证“自动配置是否生效”一个实用的验证手法在application.yml关闭某个自动配置观察行为变化。比如我们引入 Redis starter 后再写一个测试检查RedisTemplateBean 是否存在// 文件路径src/test/java/com/example/demo/RedisBeanCheckTest.java package com.example.demo; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; SpringBootTest class RedisBeanCheckTest { Autowired(required false) private RedisTemplateString, String redisTemplate; Test void contextLoads() { System.out.println(RedisTemplate is null? (redisTemplate null)); } }如果 classpath 中有 Redis 相关依赖且没有排除自动配置redisTemplate不会为 null。这个测试可以帮助你理解自动配置到底注入了什么。8.2 常见启动异常排查问题现象可能原因排查思路解决方案Web server failed to start. Port 8080 was already in use端口被占用使用netstat -ano | findstr 8080或lsof -i:8080查看占用进程修改server.port配置或释放端口启动类上 SpringBootApplication 标了但 Controller 404Controller 不在启动类所在包及子包检查包路径层级将 Controller 移到启动类子包下或显式配置scanBasePackages应用启动失败提示 APPLICATION FAILED TO START自动配置条件不满足或 Bean 冲突查看日志中的失败分析器提示不要只看最后一行堆栈根据提示调整依赖、配置或排除自动配置引入了某个 starter但自动配置没生效依赖没进 classpath或条件注解不满足用mvn dependency:tree查看依赖是否真正引入添加缺失依赖或检查配置项是否满足条件application.yml 在 IDEA 中没有配置提示IDE 未识别配置文件或缓存问题在 IDEA 中右键配置文件选择标记为 Spring 配置文件安装 Spring 插件并清理缓存后重启Spring Boot 3.x 下代码报ClassNotFoundException第三方库版本不兼容 JDK/Jakarta 命名空间确认 Servlet API 从 javax 变为 jakarta使用兼容 Spring Boot 3.x 的依赖版本启动后时区不正确数据库时间差 8 小时JDBC 连接字符串未指定时区检查数据库连接 URL 和 JVM 默认时区在 URL 中增加serverTimezoneAsia/Shanghai或启动参数加-Duser.timezoneGMT88.3 依赖版本排查命令遇到依赖冲突时最常用的 Maven 命令是mvn dependency:tree查看完整依赖树确认冲突方向。比如mvn dependency:tree -Dincludesorg.springframework:spring-core只查看spring-core的依赖链。这个方法在排查“为什么我改了版本没生效”之后往往能直接定位到问题。9. 从第一节到实战最佳实践与后续学习路径第一节不需要你掌握所有细节但在学习路径上有几点建议值得现在就记住。9.1 版本先行不要盲目追新Spring Boot 的版本选择直接决定你能用哪些 JDK 特性、第三方库如何兼容。一个稳妥的策略是新项目且团队 JDK 已升到 17选择 Spring Boot 3.x 最新稳定版。存量项目还在 JDK 8停留在 Spring Boot 2.7.x不要强行升 3.x。不要在生产环境使用SNAPSHOT版本。此外引入第三方 starter 时注意它的版本要求。很多组件在 Spring Boot 3.x 下需要配套的新版本如果混用会出现NoClassDefFoundError或ClassNotFoundException而且错误信息往往不直观。9.2 多看自动配置源码是最快的学习路径当你遇到“为什么 Z 配置没生效”这类问题时第一反应不应该是百度而是找到对应的*AutoConfiguration类看它的条件注解。比如RedisAutoConfiguration上有什么条件DataSourceAutoConfiguration里默认的数据源是什么WebMvcAutoConfiguration里默认注册了哪些转换器IDE 里按住 CtrlMac 是 Command点击类名就能跳转到源码。读源码时带着“这个类在什么条件下生效、注入了什么 Bean、哪些可以通过配置覆盖”这三个问题比看任何教程都有效。9.3 合理使用 starter但不要滥用starter 是 Spring Boot 提供的一种依赖聚合方式但你不是必须给每个功能都加一个 starter。引入一个 starter 就意味着一组自动配置候选类被加载。原则上遵循“用到才引入不用就移除”。比如项目只用 JdbcTemplate 访问数据库那spring-boot-starter-data-jpa就不应该出现。9.4 从 Web 应用开始逐步深入这篇文章是第一篇建议你按以下顺序继续学习把本文的示例跑起来修改端口、上下文路径观察日志变化。练习ConfigurationProperties绑定配置。引入spring-boot-starter-data-jpa或mybatis-spring-boot-starter连接一个数据库完成一个带增删改查的接口。学习 Spring Boot 的测试体系包括SpringBootTest和MockMvc。学习 Actuator了解生产环境健康检查。学习如何将应用打成可执行 Jar 并部署到服务器。后面这些主题每一块都能单独展开成一篇文章。本文不展开只是先把路线画清楚。9.5 安全与合规提醒无论你使用什么框架接入数据库、消息队列、第三方 API 时都要注意安全边界数据库账号实行最小权限分配不要用 root 连接业务库。密码不要硬编码在代码和配置中优先使用环境变量或配置中心。暴露的 Actuator 端点要控制访问范围生产环境避免开放/actuator/env、/actuator/heapdump等敏感端点。对用户上传文件做好类型校验和大小限制。Spring Boot 默认的自动配置在某些场景下会绑定宽松的配置前缀如果你的应用暴露到公网务必检查敏感配置是否被外部访问到。安全这块宁可多花时间也不要心存侥幸。10. 小结与下一节预告回到这一节的核心问题Spring Boot 是什么做了哪些事情从本质上说Spring Boot 是 Spring 生态的“开箱即用”封装层。它没有改变 Spring 的编程模型但通过 starter 依赖管理、自动配置、内嵌服务器和约定优于配置把 Java Web 项目的搭建成本降到了极低。它让开发者能把注意力集中在业务代码上而不是消耗在环境配置里。这一节我们重点掌握了Spring Boot 与传统 Spring 项目的本质区别。SpringBootApplication组合注解的作用。自动装配的判断逻辑与条件注解原理。一个 Spring Boot 应用的完整启动路径。最小可运行 Web 应用的搭建与验证方法。配置体系、多环境配置、常见启动异常排查。下一节可以顺着自动装配继续深入比如从源码角度拆解SpringApplication.run()到底执行了哪些步骤也可以直接进入实战讲 Spring Boot 如何整合 MySQL、MyBatis 并完成第一个带数据库的 REST 接口。如果你对某个方向更感兴趣可以在评论区告诉我。最后给你一个练习建议不要只看文章试着把本文的示例从零手写一遍不要复制粘贴然后修改端口和上下文路径再观察启动日志的每一行分别来自哪个模块。这种“手过一遍 看日志 读源码”的方式是理解 Spring Boot 最有效的路径。建议先收藏这篇文章等跑通示例后再回头对照原理收获会更大。