SpringBoot 和 Spring 的区别是什么?

#Java#面试八股

SpringBoot 和 Spring 的区别是什么?

结论先行:Spring 是"容器 + 内核",核心价值是 IoC 容器与 AOP,解决对象创建、依赖装配和横切逻辑复用;Spring Boot 是长在 Spring 之上的"脚手架 + 运行时约定",用起步依赖(starter)、自动配置(auto-configuration)和内嵌容器(embedded container)把集成成本压到最低。两者不是替代关系——去掉 Boot 依然是完整的 Spring,Boot 只是让 Spring 开箱即跑。

一、定位对比

维度Spring FrameworkSpring Boot
本质轻量级容器与框架集合构建在 Spring 之上的快速开发脚手架
依赖管理手工选坐标、手工对齐版本starter 聚合依赖,BOM 统一版本
配置方式XML / 注解,大量显式配置约定优于配置,yml/properties 覆盖默认值
容器创建自己 new ApplicationContext由 SpringApplication 创建并 refresh
Web 部署打 war 包丢进外部 Tomcat内嵌 Tomcat/Jetty/Undertow,java -jar 直跑
入口无固定入口@SpringBootApplication + main 方法
运维能力需自行集成actuator 提供健康检查、指标、环境端点
典型缺点配置繁琐、集成踩坑多"魔法"隐式、升级牵动全家、包体积大

二、Boot 在 Spring 之上补了哪三层

┌──────────────────────────────────────────┐
│  Spring Boot:装配层 + 运行时             │
│  starter(依赖聚合)                      │
│  auto-configuration(条件装配)           │
│  embedded server(内嵌容器)              │
└───────────────────┬──────────────────────┘
                    │ 依赖、非替换
┌───────────────────▼──────────────────────┐
│  Spring Framework:内核                   │
│  IoC 容器 · AOP · 事务 · MVC · 事件       │
└──────────────────────────────────────────┘
  1. 依赖层:starter 把"某个场景需要的一堆坐标"打包成一个依赖,BOM 锁死版本,避免版本地狱。
  2. 装配层:@EnableAutoConfiguration 依据 classpath 上的类、已有 Bean、配置项,决定注册哪些 BeanDefinition。
  3. 运行层:内嵌容器 + SpringApplication 启动编排,把"部署到容器"改成"启动一个进程"。

三、代码对比:同一个数据源

// 纯 Spring:配置类里手写每个组件,包括容器本身
@Configuration
@EnableTransactionManagement
public class PureSpringConfig {
    @Bean
    public DataSource dataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl("jdbc:mysql://localhost:3306/demo");
        ds.setUsername("root");
        ds.setPassword("root");
        return ds;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource ds) throws Exception {
        SqlSessionFactoryBean f = new SqlSessionFactoryBean();
        f.setDataSource(ds);
        return f.getObject();
    }
}
// Spring Boot:只声明差异,其余走自动配置
@SpringBootApplication          // = @SpringBootConfiguration + @ComponentScan + @EnableAutoConfiguration
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
# 只覆盖需要改的默认值,DataSource 由 DataSourceAutoConfiguration 自动装配
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo
    username: root
    password: root

四、常见追问

  • 问:用了 Spring Boot 还能用 XML 吗? 能。@ImportResource("classpath:legacy.xml") 即可混合,只是不再是主流写法。
  • 问:Spring Boot 2.x 与 3.x 的关键差别? 3.x 要求 Java 17、把 javax.* 迁到 jakarta.*、基于 Spring Framework 6,并支持 GraalVM 原生镜像(AOT 处理)。
  • 问:自动配置会不会覆盖我自己的 Bean? 不会。自动配置类普遍带 @ConditionalOnMissingBean,用户显式声明的 Bean 优先,所以"自定义覆盖默认"是设计好的路径。
  • 问:什么场景适合不用 Boot? 需要极致裁剪的中间件、必须打成 war 部署到既有容器、或对启动内存与包体积敏感的 SDK 类项目。

小结

  • Spring 提供能力,Spring Boot 提供开箱即用的装配与运行方式;
  • 记住三件事:starter 管依赖、自动配置管装配、内嵌容器管运行;
  • 面试答"区别"时,先给定位,再给表格化对比,最后补一句"Boot 不替代 Spring",层次就清楚了。
笔记加载中…