Spring Boot <--> Spring Framework :从入门到迁移实践

374 阅读7分钟

在 Java 开发领域,Spring Framework 是生态基石,而 Spring Boot 则是基于它的快速开发脚手架。两者版本紧密绑定,理解其对应关系是项目选型、升级和排错的关键。本文将系统梳理 Spring Boot 三大主流版本与 Spring Framework 的匹配逻辑,结合实际场景说明核心差异,并附上可直接复用的示例代码,帮助开发者高效选型与迁移。

一、版本对应核心逻辑

Spring Boot 的本质是 Spring Framework 的 “封装器”:它通过自动配置简化了 Spring 应用的搭建,但核心功能(如 IoC 容器、AOP、事务管理)完全依赖 Spring Framework。因此:

  1. Spring Boot 版本决定了底层 Spring Framework 版本(无需手动指定,Maven/Gradle 会通过父依赖自动管理);

  2. 大版本升级必然伴随 Spring Framework 重大变更(如 JDK 版本要求、API 调整、依赖规范升级);

  3. 小版本迭代(如 2.7.x→2.7.18)仅修复 Bug / 优化性能,不改变核心依赖与 API。

先通过一张速查表建立整体认知:

二、Spring Boot 1.x ↔ Spring Framework 4.x( Legacy 版本)

1. 核心说明

Spring Boot 1.x 是 2014 年发布的初代版本,基于 Spring Framework 4.x 构建,定位是 “简化 Spring 配置”。它解决了传统 Spring 项目 XML 配置繁琐的痛点,但受限于当时的技术生态,存在明显的时代特征:

  • JDK 支持:初期支持 JDK 6/7,后期版本(1.5+)逐步迁移到 JDK 8;
  • 核心依赖:内置 Tomcat 7/8、Jetty 8/9,默认连接池为 Tomcat JDBC(非 HikariCP);
  • 自动配置:基于 Spring 4.x 的 @Conditional 注解实现,但自动配置类数量较少(约 50+);
  • 现状:2019 年停止维护,仅极少数遗留系统在使用,不建议新项目采用

2. 典型场景示例代码

(1)项目依赖配置(pom.xml)

xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- 父依赖:Spring Boot 1.5.x(基于 Spring Framework 4.3.x) -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.22.RELEASE</version> <!-- 1.x 最后一个稳定版 -->
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>springboot1-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <!-- 属性配置:JDK 8(1.5.x 推荐版本) -->
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <!-- 核心依赖:仅支持传统 Servlet 开发 -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId> <!-- 内置 Tomcat 8.5 -->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId> <!-- 基于 Spring 4.x ORM -->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope> <!-- 依赖 JUnit 4 -->
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>1.5.22.RELEASE</version> <!-- 与 Spring Boot 版本一致 -->
            </plugin>
        </plugins>
    </build>
</project>

(2)控制器示例(传统 Servlet 风格)

Spring Boot 1.x 仅支持基于 Servlet 的同步开发,且依赖 Spring 4.x 的 @RestController 注解(Spring 4.0 新增):

java

运行

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

// Spring 4.x 引入的 @RestController(= @Controller + @ResponseBody)
@RestController
public class HelloController {

    // Spring 4.3 新增的 @GetMapping(替代 @RequestMapping(method = RequestMethod.GET))
    @GetMapping("/hello")
    public String hello() {
        // 依赖 Spring 4.x 的 Web MVC 核心能力
        return "Hello Spring Boot 1.x + Spring 4.x";
    }
}

(3)启动类与配置

java

运行

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// Spring Boot 1.x 核心注解(自动包含 @ComponentScan、@EnableAutoConfiguration)
@SpringBootApplication
public class SpringBoot1DemoApplication {

    public static void main(String[] args) {
        // 启动 Spring 4.x 的 IoC 容器
        SpringApplication.run(SpringBoot1DemoApplication.class, args);
    }
}

三、Spring Boot 2.x ↔ Spring Framework 5.x(主流稳定版本)

1. 核心说明

Spring Boot 2.x 是 2018 年发布的重大升级,基于 Spring Framework 5.x 构建,是目前企业级开发的 主流版本(安全维护至 2025 年)。它在 1.x 基础上实现了质的飞跃:

  • JDK 要求:强制最低 JDK 8,支持 JDK 9-17(2.7.x 支持至 JDK 17);
  • 核心升级
    • 引入 Spring 5.x 的 响应式编程模型(WebFlux),支持非阻塞开发;
    • 替换默认连接池为 HikariCP(性能比 Tomcat JDBC 提升 50%+);
    • 升级底层依赖:Tomcat 8.5+/9.x、Spring Data 2.x、Spring Security 5.x;
  • 开发体验:自动配置类扩展至 100+,支持 YAML 配置、Actuator 监控等;
  • 适用场景:绝大多数企业级应用(微服务、后台管理系统、API 服务)。

2. 典型场景示例代码

(1)项目依赖配置(pom.xml)

xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- 父依赖:Spring Boot 2.7.x(基于 Spring Framework 5.3.x) -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.18</version> <!-- 2.x 最新稳定版 -->
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>springboot2-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>1.8</java.version> <!-- 最低 1.8,可升级至 17 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- 1. 传统 Servlet 开发(Spring MVC) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId> <!-- 默认 Tomcat 9 -->
        </dependency>

        <!-- 2. 响应式开发(Spring 5.x 新增 WebFlux) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId> <!-- 内置 Netty -->
        </dependency>

        <!-- 3. Redis 集成(默认 Lettuce 客户端,Spring 5.x 优化) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!-- 4. 测试依赖(JUnit 5,Spring 5.x 推荐) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclude>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId> <!-- 排除 JUnit 4 -->
                </exclude>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!-- 支持 JDK 17 编译 -->
                <configuration>
                    <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

(2)响应式控制器(Spring 5.x WebFlux)

这是 Spring 5.x 最核心的新特性,基于 Reactive Streams 规范,支持非阻塞 I/O:

java

运行

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono; // Spring 5.x 引入的响应式类型

// 响应式控制器(与 Spring MVC 注解兼容,但返回值为响应式类型)
@RestController
public class ReactiveHelloController {

    // 返回 Mono(0 或 1 个元素),支持异步非阻塞
    @GetMapping("/reactive/hello")
    public Mono<String> reactiveHello() {
        // 模拟异步操作(如 Redis 查询、HTTP 调用)
        return Mono.just("Hello Spring Boot 2.x + Spring 5.x WebFlux")
                .delayElement(java.time.Duration.ofMillis(500)); // 延迟 500ms,不阻塞线程
    }
}

(3)Redis 操作(Lettuce 客户端,Spring 5.x 优化)

Spring Boot 2.x 弃用 Jedis,默认使用 Lettuce(基于 Netty 的非阻塞客户端),配合 Spring 5.x 的 StringRedisTemplate 简化操作:

java

运行

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
public class RedisController {

    // Spring 5.x 优化的 StringRedisTemplate(自动注入 Lettuce 连接)
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @GetMapping("/redis/set/{key}/{value}")
    public String setRedisKey(@PathVariable String key, @PathVariable String value) {
        // 基于 Spring 5.x 的 Redis 模板操作
        stringRedisTemplate.opsForValue().set(key, value);
        return "Set Success: " + key + "=" + value;
    }

    @GetMapping("/redis/get/{key}")
    public String getRedisKey(@PathVariable String key) {
        String value = stringRedisTemplate.opsForValue().get(key);
        return "Get Result: " + key + "=" + (value == null ? "null" : value);
    }
}

(4)单元测试(JUnit 5,Spring 5.x 推荐)

Spring Boot 2.x 默认使用 JUnit 5,替代 1.x 的 JUnit 4:

java

运行

import org.junit.jupiter.api.Test; // JUnit 5 注解
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import static org.junit.jupiter.api.Assertions.assertEquals;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloControllerTest {

    @Autowired
    private TestRestTemplate testRestTemplate;

    @Test
    void testHello() {
        // 测试传统 MVC 接口
        String result = testRestTemplate.getForObject("/hello", String.class);
        assertEquals("Hello Spring Boot 2.x + Spring 5.x", result);
    }
}

四、Spring Boot 3.x ↔ Spring Framework 6.x(未来主流版本)

1. 核心说明

Spring Boot 3.x 是 2022 年发布的里程碑版本,基于 Spring Framework 6.x 构建,是面向未来的 新一代版本。它的核心变化是 “拥抱 Jakarta EE 9+” 和 “原生镜像支持”:

  • JDK 要求:强制最低 JDK 17(Java SE 17 是 LTS 版本,支持至 2029 年);
  • 核心升级
    • 全面迁移至 Jakarta EE 9+(原 Java EE),包名从 javax.* 改为 jakarta.*(如 jakarta.servlet);
    • 支持 GraalVM 原生镜像,启动时间缩短 90%+,内存占用降低 50%+;
    • 基于 Spring 6.x 的 AOT( Ahead-of-Time )编译,优化运行时性能;
    • 升级底层依赖:Tomcat 10.x、Spring Data 3.x、Spring Security 6.x;
  • 适用场景:新启动的微服务、云原生应用、对性能要求高的系统;
  • 迁移注意:需修改所有 javax.* 包导入(如 javax.servlet.http.HttpServletRequestjakarta.servlet.http.HttpServletRequest)。

2. 典型场景示例代码

(1)项目依赖配置(pom.xml)

xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- 父依赖:Spring Boot 3.2.x(基于 Spring Framework 6.1.x) -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version> <!-- 3.x 最新稳定版 -->
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>springboot3-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>17</java.version> <!-- 强制最低 JDK 17 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- Web 依赖:基于 Jakarta EE 9+,内置 Tomcat 10 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- 原生镜像支持(GraalVM) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aot</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- 测试依赖:JUnit 5,基于 Jakarta EE -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!-- 配置原生镜像构建 -->
                <configuration>
                    <image>
                        <name>com.example/springboot3-demo:%s</name> <!-- 镜像名称 -->
                    </image>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

(2)Jakarta EE 包名迁移(核心变化)

Spring Boot 3.x 所有与 Servlet、JPA 相关的包均从 javax.* 改为 jakarta.*,这是迁移的核心工作:

java

运行

// Spring Boot 2.x 写法(javax.*)
// import javax.servlet.http.HttpServletRequest;

// Spring Boot 3.x 写法(jakarta.*)
import jakarta.servlet.http.HttpServletRequest; // 包名变更
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class JakartaHelloController {

    @GetMapping("/jakarta/hello")
    public String jakartaHello(HttpServletRequest request) {
        // 使用 Jakarta EE 的 HttpServletRequest
        String clientIp = request.getRemoteAddr();
        return "Hello Spring Boot 3.x + Spring 6.x(Jakarta EE),Client IP: " + clientIp;
    }
}

(3)GraalVM 原生镜像构建(Spring 6.x 新特性)

Spring Boot 3.x 支持将应用打包为 GraalVM 原生镜像,大幅提升启动速度。构建命令与效果如下:

  1. 安装 GraalVM 17+(参考 GraalVM 官网);

  2. 执行构建命令

    bash

    # 生成原生镜像(需耐心等待,首次构建约 5-10 分钟)
    mvn spring-boot:build-image
    
  3. 启动原生镜像

    bash

    # 启动速度 < 100ms,内存占用 < 100MB
    docker run -p 8080:8080 com.example/springboot3-demo:0.0.1-SNAPSHOT
    

(4)AOT 编译优化(Spring 6.x 新特性)

Spring 6.x 引入 AOT 编译,在构建时提前生成 Bean 定义元数据,减少运行时反射开销。只需在 application.yml 中开启:

yaml

# application.yml
spring:
  aot:
    processing:
      mode: native # 开启 AOT 编译(原生镜像构建时自动生效)
server:
  port: 8080

五、版本选型与迁移建议

1. 新项目选型

  • 优先选 Spring Boot 3.x:若团队已升级 JDK 17,且无 legacy 依赖(如旧版 Dubbo、Shiro),3.x 的原生镜像和性能优势明显;
  • 次选 Spring Boot 2.7.x:若需兼容 JDK 8 或依赖未支持 Jakarta EE 的组件,2.7.x 是安全稳定的选择(维护至 2025 年);
  • 拒绝 Spring Boot 1.x:已停止维护,存在安全漏洞,无任何理由选用。

2. 版本迁移注意事项

(1)1.x → 2.x 迁移

  • 升级 JDK 至 8+;
  • 替换 spring-boot-starter-parent 版本为 2.7.x;
  • 移除 Jedis 依赖(改用 Lettuce);
  • 测试用例从 JUnit 4 迁移到 JUnit 5。

(2)2.x → 3.x 迁移

  • 升级 JDK 至 17+;
  • 全局替换 javax.*jakarta.*(可使用 IDE 批量替换);
  • 检查依赖兼容性(如 MyBatis 需升级至 3.5.10+,Spring Cloud 需升级至 2022.0.x+);
  • 若使用原生镜像,需避免反射、动态代理等不兼容特性。

六、总结

Spring Boot 与 Spring Framework 的版本对应关系,本质是 “上层封装” 与 “底层核心” 的协同进化:

  • 1.x 是 “简化配置” 的起点,基于 Spring 4.x 解决了 XML 臃肿问题;

  • 2.x 是 “性能与体验” 的飞跃,基于 Spring 5.x 引入响应式编程;

  • 3.x 是 “云原生与未来” 的布局,基于 Spring 6.x 拥抱 Jakarta EE 和原生镜像。

无论选型还是迁移,核心是匹配团队技术栈与业务需求:新项目大胆用 3.x,旧项目稳步迁 2.x, legacy 项目逐步淘汰 1.x。掌握版本对应关系,能让你在 Spring 生态中少走弯路,高效开发。