SpringBoot 和 Spring 的区别是什么?


面试考察点

  1. 认知深度:面试官不仅仅是想知道 "SpringBoot 更方便" 这个表层结论,更是想看你能否讲清楚 SpringBoot 到底帮你自动做了哪些事,以及背后的原理(自动配置、起步依赖等)。

  2. 历史演进理解:能否说出 Spring 时代的开发痛点(配置地狱、版本冲突、手动部署),以及 SpringBoot 如何逐一解决这些痛点。

  3. 底层原理:能否讲清楚 @SpringBootApplication 注解背后的三个核心注解、spring.factories 自动配置的加载机制、内嵌 Tomcat 的启动流程。

核心答案

先说结论:SpringBoot 不是 Spring 的替代品,而是 Spring 的 "快速开发脚手架"。它底层 100% 依赖 Spring 框架,只是在 Spring 之上做了一层 "约定优于配置" 的封装,让你开箱即用。

对比维度SpringSpringBoot
核心定位企业级 Java 开发框架Spring 的快速开发脚手架
配置方式大量 XML / Java 配置约定优于配置,零 XML
依赖管理手动管理版本,容易冲突起步依赖(Starter),自动管理版本
内嵌服务器无,需手动部署 WAR 到外部容器内嵌 Tomcat/Jetty/Undertow,java -jar 直接运行
自动配置无,手动配 Bean根据类路径自动装配(@EnableAutoConfiguration
生产监控无内置Actuator 提供健康检查、指标监控
启动方式部署到 Servlet 容器独立运行,main() 方法启动

一句话总结:Spring 是引擎,SpringBoot 是带自动挡的车。引擎还是那个引擎,但不用你手动挂挡了。

深度解析

一、从 Spring 的痛点说起

没用过纯 Spring 的人可能不知道当年有多痛苦。我最早用 Spring MVC 做项目的时候,一个 web.xmlapplicationContext.xml 能写到几百行。

Spring 时代的典型开发流程

上面的图展示了纯 Spring 开发的典型痛点:

  • 依赖版本冲突:Spring 各模块版本要自己管理,不同模块之间的版本兼容性容易出问题
  • 配置地狱:光配置文件就几百行,而且每个项目都差不多,大量重复劳动
  • 手动配置组件:数据源、事务管理器、视图解析器这些基础组件每次都要手动配
  • 部署繁琐:打 WAR 包、部署到外部 Tomcat、处理端口冲突和类冲突

SpringBoot 的出现就是为了解决这些痛点。

二、SpringBoot 的三大核心特性

特性 1:起步依赖(Starter)

<!-- Spring 时代:手动引入一堆依赖,还要管版本 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.20</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>5.3.20</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.3</version>
</dependency>
<!-- 还要引入十几个... -->

<!-- SpringBoot:一个 Starter 搞定 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- 不用写版本!parent POM 统一管理 -->
</dependency>

一个 spring-boot-starter-web 就帮你把 Spring MVC、Jackson、Tomcat、验证框架等常用依赖全引进来了,版本都帮你协调好了。

常用 Starter:

Starter包含的功能
spring-boot-starter-webSpring MVC + Tomcat + Jackson
spring-boot-starter-data-jpaSpring Data JPA + Hibernate
spring-boot-starter-data-redisLettuce / Jedis + Spring Data Redis
spring-boot-starter-securitySpring Security
spring-boot-starter-testJUnit 5 + Mockito + AssertJ

特性 2:自动配置(Auto-Configuration)

这是 SpringBoot 最核心的特性,也是面试官最爱追问的。

@SpringBootApplication // 这个注解背后做了三件事
public class MyApp {
    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }
}

@SpringBootApplication 其实是三个注解的组合:

@SpringBootConfiguration     // 本质就是 @Configuration,标记配置类
@EnableAutoConfiguration     // 核心!开启自动配置
@ComponentScan               // 组件扫描,扫描当前包及子包

@EnableAutoConfiguration 的原理

上面的图展示了自动配置的核心流程:

  • 第 ① 步:SpringBoot 启动时,通过 SpringFactoriesLoader 扫描所有 jar 包下的 META-INF/spring.factories 文件(SpringBoot 3.x 改为 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports),找到所有自动配置类的全限定名。
  • 第 ② 步:加载这些自动配置类,比如你引入了 spring-boot-starter-data-redis,就会加载 RedisAutoConfiguration
  • 第 ③ 步:关键环节。不是所有自动配置类都会生效,每个配置类上都有 @Conditional 系列注解来做条件判断。比如 @ConditionalOnClass(RedisOperations.class) 意味着只有类路径上有 RedisOperations 类时才生效。你没引入 Redis 依赖,这个配置类就会被跳过。
  • 第 ④ 步:条件满足的配置类自动创建 Bean 并注册到容器中。你什么配置都不用写,Bean 就帮你配好了。

这就是 "约定优于配置" 的精髓:你引入了 Redis Starter,我就默认帮你配一个 Redis 连接工厂;你想自定义,就在 application.yml 里覆盖默认值。

特性 3:内嵌服务器

Spring 时代需要打 WAR 包部署到外部 Tomcat。SpringBoot 直接把 Tomcat 嵌入到应用里:

<!-- spring-boot-starter-web 默认内嵌 Tomcat -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 想换 Jetty?排除 Tomcat,引入 Jetty -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

启动方式:

# 打包
mvn clean package

# 一行命令启动
java -jar myapp.jar

# 指定端口
java -jar myapp.jar --server.port=8081

不需要安装 Tomcat,不需要部署 WAR 包,java -jar 一行命令搞定。这对 Docker 容器化部署极其友好。

三、SpringBoot 没有替代什么

一个常见的误区是 "SpringBoot 替代了 Spring"。不是的。

  • SpringBoot 底层就是 Spring。IoC 容器、AOP、事务管理、MVC 这些核心功能全部来自 Spring 框架
  • SpringBoot 只是在 Spring 之上做了一层 "自动配置 + 起步依赖 + 内嵌容器" 的封装
  • 你在 SpringBoot 里用的 @Autowired@Transactional@RequestMapping 全都是 Spring 的注解

上面的层次图说明:SpringBoot 是在 Spring 之上的一层封装,底层完全依赖 Spring。

面试高频追问

  1. @SpringBootApplication 注解背后做了什么?

    • 它是 @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan 三个注解的组合。@EnableAutoConfiguration 负责加载自动配置类,@ComponentScan 负责扫描当前包下的组件。
  2. SpringBoot 的自动配置原理是什么?

    • 启动时通过 SpringFactoriesLoader 加载 META-INF/spring.factories 中的自动配置类,然后根据 @ConditionalOnClass@ConditionalOnMissingBean 等条件注解判断是否生效。本质是 "你引入了什么依赖,我就帮你自动配什么"。
  3. SpringBoot 怎么切换内置服务器?

    • 排除默认的 spring-boot-starter-tomcat,引入 spring-boot-starter-jettyspring-boot-starter-undertow 即可。
  4. SpringBoot 的配置文件加载顺序是什么?

    • application.yml / application.properties,支持多环境配置(application-dev.ymlapplication-prod.yml),通过 spring.profiles.active 激活。加载顺序:默认配置 → 应用配置 → profile 配置 → 命令行参数,后者覆盖前者。

常见面试变体

  • "SpringBoot 的自动配置原理是什么?"
  • "SpringBoot 的 Starter 是什么?自己写过 Starter 吗?"
  • "SpringBoot 为什么不需要 XML 配置?"
  • "Spring、SpringMVC、SpringBoot 之间是什么关系?"

记忆口诀

核心区别:Spring 是框架,SpringBoot 是脚手架。底层还是 Spring,上面加了一键配置。

三大特性:起步依赖管版本,自动配置省代码,内嵌容器直接跑。

自动配置本质:引入什么依赖,就帮你自动配什么;想自定义,覆盖默认值就行。

总结

Spring 和 SpringBoot 的关系是 "框架" 和 "脚手架" 的关系。SpringBoot 底层 100% 依赖 Spring,只是在上面加了起步依赖、自动配置、内嵌容器三件套。面试时先说核心区别,再展开三大特性(重点讲自动配置的 @Conditional 原理),最后强调 "SpringBoot 没有替代 Spring,只是让 Spring 用起来更简单"。这条线拉下来,面试官就清楚你是真用过,而不只是背了概念。