image

一、本质关系:脚手架而非替代品

很多初学者误以为 Spring Boot 是 Spring 的"升级版"或"替代者",这是一个常见误区。
准确说法:Spring Boot 是基于 Spring Framework 的快速开发脚手架(Scaffold)。它像给 Spring 穿上了一件"自动化外衣"——底层依然是 Spring 核心的 IoC、AOP、ORM,但上层通过约定优于配置(Convention Over Configuration)的理念,将繁琐的 XML/注解配置压缩为近乎零配置。
记忆公式
Spring = 发动机 + 底盘(核心机制) Spring Boot = 发动机 + 底盘 + 自动驾驶(自动配置 + Starter 依赖管理)

二、核心差异全景对比

维度 Spring Framework Spring Boot 影响评估
配置方式 XML 或显式 Java Config,需手动定义每个 Bean 自动配置(Auto-configuration),基于 classpath 推断 ⭐⭐⭐ 开发效率提升 10 倍
依赖管理 手动引入,需处理版本冲突("依赖地狱") Starter 一键引入,父工程统一版本(BOM) ⭐⭐⭐ 杜绝版本不兼容
部署方式 WAR 包 + 外部 Tomcat 可执行 JAR 包 + 内嵌服务器(Tomcat/Jetty/Undertow) ⭐⭐ 云原生/微服务基石
启动流程 手动构建 ApplicationContext SpringApplication.run() 一键启动 ⭐⭐ 降低入门门槛
监控运维 需手动集成 Actuator 自动提供健康检查、指标监控端点 ⭐⭐ 生产环境必备
表 1:Spring vs Spring Boot 架构层面核心差异

三、深度拆解:4 个关键差异的技术实现

3.1 配置方式:从"手搓零件"到"约定装配"

Spring Framework 的繁琐(以整合 MyBatis 为例)
需要显式配置 DataSource、SqlSessionFactory、MapperScanner、TransactionManager 四个核心 Bean,约 50-80 行配置代码。任何一个 Bean 配置错误(如 Mapper XML 路径写错)都会导致启动失败。
// Spring 手动配置示例(痛点:样板代码多,易出错)
@Configuration
public class MyBatisConfig {
    @Bean
    public DataSource dataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setUrl("jdbc:mysql://localhost:3306/test");
        // ... 省略 10+ 行属性设置
        return ds;
    }
    
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource ds) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(ds);
        // 路径硬编码,一旦目录结构调整需重新编译
        factory.setMapperLocations(new PathMatchingResourcePatternResolver()
            .getResources("classpath:mapper/*.xml"));
        return factory.getObject();
    }
    // 还需配置 MapperScannerConfigurer、TransactionManager...
}
 
Spring Boot 的极简(同样的功能)
只需引入 mybatis-spring-boot-starter,在 application.yml 中写 4 行配置,启动类加 @MapperScan 即可。
# application.yml - Spring Boot 的声明式配置
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: 123456
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.example.entity
 
技术原理:Spring Boot 的 @EnableAutoConfiguration 注解会在启动时扫描 classpath 下的 META-INF/spring.factories 文件,发现 MyBatis 相关类存在时,自动注册预定义的 SqlSessionFactory Bean,且属性值从 Environment 中自动绑定(即上述 YAML 内容)。

3.2 依赖管理:Starter 机制如何终结"依赖地狱"

Spring Framework 项目中,开发者常陷入版本兼容性陷阱
  • Spring 5.3.x 需要搭配 MyBatis 3.5.x
  • Spring 6.x(Jakarta EE 命名空间)要求 MyBatis 3.6+
  • 若同时引入 Druid 和 Spring Transaction,需确保两者版本匹配
Spring Boot 的解决方案:Starter Parent BOM
pom.xml 中继承 spring-boot-starter-parent
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.1</version>
</parent>

<dependencies>
    <!-- 无需写版本号,自动继承 tested & compatible 版本 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>3.0.0</version> <!-- 仅第三方 starter 需指定 -->
    </dependency>
</dependencies>
核心价值:Spring Boot 通过 BOM(Bill of Materials) 锁定了 200+ 个常用依赖的版本矩阵,确保它们经过兼容性测试。这就像 Maven/Gradle 的"推荐配置快照"。

3.3 部署架构:从 Servlet 容器到内嵌服务器

传统 Spring(Servlet 时代)
  • 必须打包为 WAR 格式
  • 部署到外部 Tomcat/JBoss(应用服务器)
  • 需要维护 web.xmlWebApplicationInitializer
Spring Boot(云原生时代)
  • 打包为可执行 JAR(Fat Jar)
  • 内嵌 Tomcat/Jetty/Undertow(默认 Tomcat)
  • main() 方法直接启动,一行命令部署:java -jar app.jar
微服务场景优势
  • 契合 Docker 镜像构建(一层 JAR 即可)
  • 契合 Kubernetes 健康探针(Actuator 端点原生支持)
  • 水平扩容时无需配置外部服务器集群

3.4 自动配置:@SpringBootApplication 背后做了什么?

@SpringBootApplication 是一个组合注解,等价于:
@Configuration              // 标记为配置类
@EnableAutoConfiguration    // 开启自动配置(核心)
@ComponentScan              // 组件扫描
 
自动配置的决策流程
  1. 条件评估:使用 @ConditionalOnClass 检测 classpath 是否存在某类(如检测到 org.apache.catalina.startup.Tomcat 则判定需 Web 环境)
  2. 属性绑定:通过 @EnableConfigurationProperties 将 YAML/Properties 中的值注入配置类(如 ServerProperties 绑定 server.port
  3. Bean 注册:满足条件后,自动向 IoC 容器注册 Bean(如 DispatcherServletDataSourceAutoConfiguration
禁用自动配置示例(当需要手动接管时):
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class Application { ... }
 

四、核心联系:Spring Boot 如何依赖 Spring?

  1. 底层引擎完全一致:Spring Boot 的 run() 方法最终调用的仍是 Spring 的 ConfigurableApplicationContext 初始化流程
  2. 注解体系完全兼容@Autowired@Service@Transactional@Aspect 等 Spring 原生注解无需任何修改
  3. 扩展机制统一:Spring 的 BeanPostProcessorApplicationListener 等扩展点在 Spring Boot 中同样适用
一句话总结:Spring Boot 没有发明新的编程模型,只是优化了 Spring 应用的启动和配置体验

五、选型指南:什么时候该用哪个?

优先选择 Spring Boot(90% 场景)

  • 微服务架构:配合 Spring Cloud,快速构建独立服务
  • 快速原型开发:MVP 验证、POC 概念验证
  • 云原生部署:容器化、Serverless 场景
  • 团队技能参差:降低配置错误率,统一开发规范

仍需原生 Spring Framework(10% 场景)

  • 遗留系统维护:基于 Spring 4.x 的老系统逐步迁移
  • 深度定制需求:需要完全接管 Bean 生命周期,禁用所有自动配置
  • 非 Web 环境:简单的命令行工具或批处理(虽然 Spring Boot 也支持,但原生 Spring 更轻)
  • 特殊容器限制:必须部署到客户提供的特定版本 WebLogic/WebSphere(企业级应用服务器)

六、面试高频考点速记

Q1:Spring Boot 的自动配置原理是什么?
答:基于 @EnableAutoConfiguration,通过 spring.factories 文件加载候选配置类,再利用 @Conditional 条件注解(如 @ConditionalOnClass)根据 classpath 和已定义 Bean 进行条件过滤,最终注册合适的 Bean 到容器。
Q2:Spring Boot 2.x 和 3.x 最大的区别是什么?
答:Spring Boot 3.x(基于 Spring Framework 6)迁移到了 Jakarta EE 9 命名空间(javax.*jakarta.*),要求 Java 17+,并引入了新的 Observations API 和 GraalVM Native Image 支持。
Q3:为什么 Spring Boot 的 JAR 可以直接运行?
答:使用了自定义的 Loader(LaunchedURLClassLoader),在 JAR 的 MANIFEST.MF 中指定 Main-ClassJarLauncher,它会创建类加载器加载内嵌的 Tomcat 和依赖 JAR,最后反射调用用户的 main 方法。

七、总结:从"装修毛坯房"到"入住精装房"

类比维度 Spring Framework Spring Boot
房屋类型 毛坯房 精装房
交付状态 提供水电管线(IoC/AOP),需自行装修 拎包入住,家具家电(Starter)齐全
改造自由度 极高,可从地基改起 较高,支持局部重装(自定义配置覆盖默认配置)
适用人群 建筑师(架构师) 住户(开发者)
最终建议:现代 Java 开发应默认选择 Spring Boot,只有在遇到自动配置无法满足的深坑时,才考虑回到 Spring Framework 的底层机制进行定制。理解两者的关系,能帮助你在架构选型时做出更理性的决策。