Skip to content

SpringBoot4与Spring7新特性

版本演进概述

新一代框架的里程碑

2025年11月,Spring团队正式发布了Spring Framework 7.0Spring Boot 4.0,这是继Spring 6和Spring Boot 3之后的又一次重大版本升级。此次更新带来了API版本控制、JSpecify空安全注解、内置弹性特性等革命性功能。

mermaid
graph TB
    A[Spring Framework 6] --> B[Spring Framework 7]
    C[Spring Boot 3] --> D[Spring Boot 4]
    B --> E[API版本控制]
    B --> F[JSpecify空安全]
    D --> G[Jackson 3迁移]
    D --> H[模块化架构]
    
    style B fill:#66ccff,rx:10,ry:10
    style D fill:#66ccff,rx:10,ry:10
    style E fill:#99ff99,rx:10,ry:10
    style F fill:#99ff99,rx:10,ry:10
    style G fill:#99ff99,rx:10,ry:10
    style H fill:#99ff99,rx:10,ry:10

核心更新一览

特性分类Spring Framework 7Spring Boot 4
API版本控制原生支持自动配置
空安全JSpecify注解全面集成
弹性特性@Retryable内置开箱即用
JSON处理Jackson 3支持默认Jackson 3
模块化-自动配置模块化
JDK支持JDK 17-25JDK 17-25

基线要求与依赖更新

JDK版本要求

Spring Framework 7保持JDK 17基线不变,同时全面拥抱JDK 25的所有新特性。这意味着开发者可以继续使用JDK 17,但建议升级到JDK 25以获得最佳体验。

mermaid
graph LR
    A[JDK 17] --> B[最低要求]
    C[JDK 21] --> D[推荐版本]
    E[JDK 25] --> F[完整支持]
    
    style A fill:#ffcc99,rx:10,ry:10
    style C fill:#99ccff,rx:10,ry:10
    style E fill:#99ff99,rx:10,ry:10

Jakarta EE 11基线

Spring Framework 7将Jakarta EE基线从版本9升级到版本11,带来以下变化:

mermaid
graph TB
    A[Jakarta EE 11] --> B[Servlet 6.1]
    A --> C[WebSocket 2.2]
    A --> D[Validation 3.1]
    A --> E[Persistence 3.2]
    
    B --> F[需要Tomcat 11]
    D --> G[需要Hibernate Validator 9]
    E --> H[需要Hibernate ORM 7.1]
    
    style A fill:#66ccff,rx:10,ry:10
    style B fill:#ff9999,rx:10,ry:10
    style C fill:#ff9999,rx:10,ry:10
    style D fill:#ff9999,rx:10,ry:10
    style E fill:#ff9999,rx:10,ry:10

重要变更:由于Undertow尚未兼容Servlet 6.1,Spring Boot 4暂时不支持Undertow作为内嵌Web服务器。

第三方依赖升级

依赖Spring Boot 3.xSpring Boot 4.0
Kotlin1.9.x2.2.20
Tomcat10.111.0
Jetty12.012.1
Hibernate ORM6.x7.1
Hibernate Validator8.x9.0
Jackson2.x3.x
Kafka Client3.x4.1.0
Flyway10.x11.11
Mockito5.x5.20
TestContainers1.x2.0

API版本控制

为什么需要API版本控制

在企业级应用中,API版本控制是常见需求:

  • 向后兼容:保持老客户端正常工作
  • 渐进式升级:新功能逐步发布
  • 多版本并存:支持不同版本同时运行
  • 废弃管理:规范化API废弃流程
mermaid
graph TB
    A[API版本控制需求] --> B[客户端升级]
    A --> C[新功能发布]
    A --> D[废弃旧API]
    
    B --> E[保持兼容性]
    C --> F[渐进式迭代]
    D --> G[平滑过渡]
    
    style A fill:#66ccff,rx:10,ry:10
    style E fill:#99ff99,rx:10,ry:10
    style F fill:#99ff99,rx:10,ry:10
    style G fill:#99ff99,rx:10,ry:10

四种版本控制策略

Spring Framework 7在Spring MVC和Spring WebFlux中原生支持四种版本控制策略:

mermaid
graph TB
    A[API版本控制策略] --> B[路径版本]
    A --> C[请求头版本]
    A --> D[查询参数版本]
    A --> E[媒体类型版本]
    
    B --> F["/api/v1/users"]
    C --> G["X-API-Version: 1.1"]
    D --> H["?version=1.1"]
    E --> I["Accept: vnd.api.v1+json"]
    
    style A fill:#66ccff,rx:10,ry:10
    style B fill:#99ff99,rx:10,ry:10
    style C fill:#99ff99,rx:10,ry:10
    style D fill:#99ff99,rx:10,ry:10
    style E fill:#99ff99,rx:10,ry:10

路径版本控制

最常见的版本控制方式,将版本号放在URL路径中:

java
@RestController
@RequestMapping("/api")
public class UserController {
    
    // v1版本接口
    @GetMapping(path = "/users/{id}", version = "1")
    public UserV1Response getUserV1(@PathVariable Long id) {
        User user = userService.findById(id);
        return new UserV1Response(user.getId(), user.getName());
    }
    
    // v2版本接口,返回更详细信息
    @GetMapping(path = "/users/{id}", version = "2")
    public UserV2Response getUserV2(@PathVariable Long id) {
        User user = userService.findById(id);
        return new UserV2Response(
            user.getId(), 
            user.getName(), 
            user.getEmail(),
            user.getCreatedAt()
        );
    }
}

配置API版本策略

java
@Configuration
public class ApiVersionConfig implements WebMvcConfigurer {
    
    @Override
    public void configureApiVersioning(ApiVersionConfigurer configurer) {
        configurer.usePathVersioning()      // 使用路径版本
                  .defaultVersion("1")       // 默认版本
                  .versionPrefix("v");       // 版本前缀
    }
}

请求示例

bash
# 请求v1版本
GET /api/v1/users/123

# 请求v2版本
GET /api/v2/users/123

请求头版本控制

通过HTTP请求头传递版本号:

java
@RestController
@RequestMapping("/api/orders")
public class OrderController {
    
    @GetMapping(path = "/{id}", version = "1.0")
    public OrderV1Response getOrderV1(@PathVariable Long id) {
        return orderService.getOrderV1(id);
    }
    
    @GetMapping(path = "/{id}", version = "1.1")
    public OrderV1_1Response getOrderV1_1(@PathVariable Long id) {
        // v1.1版本添加了优惠信息
        return orderService.getOrderV1_1(id);
    }
}

配置请求头版本策略

java
@Configuration
public class ApiVersionConfig implements WebMvcConfigurer {
    
    @Override
    public void configureApiVersioning(ApiVersionConfigurer configurer) {
        configurer.useHeaderVersioning()           // 使用请求头版本
                  .headerName("X-API-Version")     // 自定义请求头名称
                  .defaultVersion("1.0");
    }
}

请求示例

bash
# 请求v1.0版本
GET /api/orders/123
X-API-Version: 1.0

# 请求v1.1版本
GET /api/orders/123
X-API-Version: 1.1

API废弃处理

Spring Framework 7内置了符合RFC 9745规范的API废弃处理机制:

java
@RestController
@RequestMapping("/api/products")
public class ProductController {
    
    // 标记为废弃的API
    @GetMapping(path = "/{id}", version = "1", deprecated = true)
    @Deprecated(since = "2.0", forRemoval = true)
    public ProductV1Response getProductV1(@PathVariable Long id) {
        return productService.getProductV1(id);
    }
    
    // 新版本API
    @GetMapping(path = "/{id}", version = "2")
    public ProductV2Response getProductV2(@PathVariable Long id) {
        return productService.getProductV2(id);
    }
}

响应中会自动添加废弃信息:

http
HTTP/1.1 200 OK
Deprecation: true
Sunset: Sat, 31 Dec 2025 23:59:59 GMT
Link: </api/v2/products/123>; rel="successor-version"

客户端版本配置

使用ApiVersionInserter在客户端自动插入版本信息:

java
@Configuration
public class HttpClientConfig {
    
    @Bean
    public RestClient restClient(ApiVersionInserter inserter) {
        return RestClient.builder()
            .baseUrl("http://product-service")
            .requestInterceptor(inserter)
            .defaultHeader("X-API-Version", "2.0")
            .build();
    }
}

// 使用HTTP Interface定义客户端
@HttpExchange("/api/products")
public interface ProductClient {
    
    @GetExchange("/{id}")
    ProductResponse getProduct(@PathVariable Long id);
}

JSpecify空安全注解

什么是JSpecify

JSpecify是由OpenJDK、Google、JetBrains、Broadcom(VMware)等共同参与的标准化空安全注解项目。Spring Framework 7全面采用JSpecify注解,提供编译时空安全检查。

mermaid
graph TB
    A[JSpecify联盟] --> B[OpenJDK]
    A --> C[Google]
    A --> D[JetBrains]
    A --> E[Broadcom/VMware]
    A --> F[Sonar]
    
    style A fill:#66ccff,rx:10,ry:10
    style B fill:#99ff99,rx:10,ry:10
    style C fill:#99ff99,rx:10,ry:10
    style D fill:#99ff99,rx:10,ry:10
    style E fill:#99ff99,rx:10,ry:10
    style F fill:#99ff99,rx:10,ry:10

核心注解

Spring Framework 7提供以下空安全注解:

java
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;
import org.jspecify.annotations.NullMarked;

// 类级别标记,表示该类中所有方法默认非空
@NullMarked
@Service
public class UserService {
    
    // 参数和返回值默认非空
    public User findById(Long id) {
        return userRepository.findById(id)
            .orElseThrow(() -> new UserNotFoundException(id));
    }
    
    // 显式标记可空返回值
    public @Nullable User findByEmail(String email) {
        return userRepository.findByEmail(email).orElse(null);
    }
    
    // 显式标记可空参数
    public List<User> searchUsers(@Nullable String keyword) {
        if (keyword == null || keyword.isBlank()) {
            return userRepository.findAll();
        }
        return userRepository.searchByKeyword(keyword);
    }
}

泛型与数组支持

JSpecify注解支持复杂类型场景:

java
@NullMarked
@Service
public class OrderService {
    
    // 泛型类型注解
    public List<@NonNull Order> findAllOrders() {
        return orderRepository.findAll();
    }
    
    // 集合可能为空,但元素不为空
    public @Nullable List<@NonNull OrderItem> findOrderItems(Long orderId) {
        return orderRepository.findById(orderId)
            .map(Order::getItems)
            .orElse(null);
    }
    
    // 数组类型注解
    public @NonNull String @Nullable [] getTags(Long orderId) {
        // 数组可能为null,但数组元素不为null
        return orderRepository.findTagsById(orderId);
    }
}

IDE与工具支持

mermaid
graph TB
    A[JSpecify生态] --> B[IntelliJ IDEA 2025.3]
    A --> C[NullAway编译检查]
    A --> D[Kotlin 2自动转换]
    
    B --> E[完整数据流分析]
    C --> F[编译时报错]
    D --> G[Kotlin可空类型]
    
    style A fill:#66ccff,rx:10,ry:10
    style B fill:#99ff99,rx:10,ry:10
    style C fill:#99ff99,rx:10,ry:10
    style D fill:#99ff99,rx:10,ry:10

IntelliJ IDEA配置

IntelliJ IDEA 2025.3提供完整的JSpecify支持,包括:

  • 复杂数据流分析
  • 实时警告提示
  • 快速修复建议

NullAway编译检查

xml
<plugin>
    <groupId>com.google.errorprone</groupId>
    <artifactId>error_prone_core</artifactId>
    <version>2.25.0</version>
</plugin>

Kotlin自动转换

kotlin
// Kotlin 2自动识别JSpecify注解
class OrderController(private val orderService: OrderService) {
    
    fun getOrder(id: Long): Order {
        // 编译器知道findById不返回null
        return orderService.findById(id)
    }
    
    fun searchOrders(keyword: String?): List<Order> {
        // 编译器知道keyword可为null
        return orderService.searchOrders(keyword)
    }
}

内置弹性特性

Spring Retry集成

Spring Framework 7将Spring Retry的核心功能集成到框架中,无需额外依赖即可使用重试和并发控制特性。

mermaid
graph TB
    A[Spring Framework 7弹性特性] --> B["@Retryable重试"]
    A --> C["@ConcurrencyLimit并发控制"]
    
    B --> D[声明式重试]
    B --> E[指数退避]
    B --> F[抖动策略]
    
    C --> G[限流保护]
    C --> H[虚拟线程优化]
    
    style A fill:#66ccff,rx:10,ry:10
    style B fill:#99ff99,rx:10,ry:10
    style C fill:#99ff99,rx:10,ry:10

@Retryable声明式重试

java
@Service
public class PaymentService {
    
    @Retryable(
        retryFor = {TransientException.class, TimeoutException.class},
        maxAttempts = 3,
        backoff = @Backoff(
            delay = 1000,      // 初始延迟1秒
            multiplier = 2,     // 指数倍数
            maxDelay = 10000,   // 最大延迟10秒
            jitter = 0.1        // 10%抖动
        )
    )
    public PaymentResult processPayment(PaymentRequest request) {
        // 调用第三方支付接口
        return paymentGateway.process(request);
    }
    
    @Recover
    public PaymentResult recoverPayment(Exception e, PaymentRequest request) {
        // 重试失败后的恢复逻辑
        log.error("支付处理失败: {}", request.getOrderId(), e);
        return PaymentResult.failed(request.getOrderId(), e.getMessage());
    }
}

重试流程时序图

mermaid
sequenceDiagram
    participant C as 客户端
    participant S as PaymentService
    participant G as 支付网关
    
    C->>S: processPayment(request)
    S->>G: 第1次调用
    G-->>S: 超时异常
    
    Note over S: 等待1秒
    
    S->>G: 第2次调用
    G-->>S: 超时异常
    
    Note over S: 等待2秒(指数退避)
    
    S->>G: 第3次调用
    G-->>S: 成功响应
    
    S-->>C: 返回支付结果

响应式重试支持

@Retryable自动适配响应式方法:

java
@Service
public class InventoryService {
    
    @Retryable(maxAttempts = 3)
    public Mono<Stock> checkStock(String productId) {
        return webClient.get()
            .uri("/inventory/{id}", productId)
            .retrieve()
            .bodyToMono(Stock.class);
    }
    
    @Retryable(maxAttempts = 3)
    public Flux<Stock> checkBatchStock(List<String> productIds) {
        return webClient.post()
            .uri("/inventory/batch")
            .bodyValue(productIds)
            .retrieve()
            .bodyToFlux(Stock.class);
    }
}

@ConcurrencyLimit并发控制

特别适合与虚拟线程配合使用的并发限制:

java
@Service
public class ReportService {
    
    // 限制最多10个并发执行
    @ConcurrencyLimit(10)
    public Report generateReport(ReportRequest request) {
        // 资源密集型操作
        return reportGenerator.generate(request);
    }
    
    // 结合重试和并发控制
    @Retryable(maxAttempts = 2)
    @ConcurrencyLimit(5)
    public ExportResult exportData(ExportRequest request) {
        return dataExporter.export(request);
    }
}

并发控制流程

mermaid
graph TB
    A[请求到达] --> B{并发数检查}
    B -->|未超限| C[立即执行]
    B -->|已超限| D[等待队列]
    
    C --> E[业务处理]
    D --> F{超时判断}
    F -->|未超时| G[获取许可]
    F -->|已超时| H[拒绝请求]
    
    G --> E
    E --> I[释放许可]
    I --> J[返回结果]
    
    style A fill:#66ccff,rx:10,ry:10
    style C fill:#99ff99,rx:10,ry:10
    style H fill:#ff9999,rx:10,ry:10

Jackson 3迁移

主要变更

Spring Boot 4默认使用Jackson 3进行JSON处理,这是一个重大的破坏性变更。

mermaid
graph TB
    A[Jackson 3变更] --> B[包名变更]
    A --> C[JsonMapper替代ObjectMapper]
    A --> D[默认序列化行为]
    
    B --> E[com.fasterxml.jackson → tools.jackson]
    C --> F[不可变/线程安全]
    D --> G[属性字母排序]
    D --> H[日期ISO-8601格式]
    
    style A fill:#66ccff,rx:10,ry:10
    style B fill:#ff9999,rx:10,ry:10
    style C fill:#99ff99,rx:10,ry:10
    style D fill:#99ff99,rx:10,ry:10

包名迁移

Jackson 2.x

java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.core.JsonProcessingException;

Jackson 3.x

java
import tools.jackson.databind.JsonMapper;
import tools.jackson.databind.JsonNode;
import tools.jackson.core.JacksonException;

JsonMapper替代ObjectMapper

Jackson 3推荐使用JsonMapper替代ObjectMapper

java
@Configuration
public class JacksonConfig {
    
    @Bean
    public JsonMapper jsonMapper() {
        return JsonMapper.builder()
            .enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)
            .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .addModule(new JavaTimeModule())
            .build();
    }
}

@Service
public class OrderSerializer {
    
    private final JsonMapper jsonMapper;
    
    public OrderSerializer(JsonMapper jsonMapper) {
        this.jsonMapper = jsonMapper;
    }
    
    public String serialize(Order order) throws JacksonException {
        return jsonMapper.writeValueAsString(order);
    }
    
    public Order deserialize(String json) throws JacksonException {
        return jsonMapper.readValue(json, Order.class);
    }
}

默认序列化行为变更

属性字母排序

java
public class User {
    private Long id;
    private String name;
    private String email;
    private LocalDateTime createdAt;
}

// Jackson 3默认输出(按字母排序)
{
    "createdAt": "2025-11-20T10:30:00",
    "email": "user@example.com",
    "id": 123,
    "name": "张三"
}

日期格式变更

java
// Jackson 2默认:时间戳格式
{"createdAt": 1732096200000}

// Jackson 3默认:ISO-8601格式
{"createdAt": "2025-11-20T10:30:00"}

兼容性策略

如需继续使用Jackson 2,可以进行配置:

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>tools.jackson</groupId>
            <artifactId>jackson-bom</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!-- 使用Jackson 2 -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.17.0</version>
</dependency>

自动配置模块化

模块化架构

Spring Boot 4将单体的spring-boot-autoconfigurespring-boot-test-autoconfigure JAR拆分为多个技术专用模块:

mermaid
graph TB
    A[Spring Boot 3.x] --> B[spring-boot-autoconfigure]
    A --> C[spring-boot-test-autoconfigure]
    
    D[Spring Boot 4.0] --> E[spring-boot-starter-webmvc]
    D --> F[spring-boot-starter-data-jpa]
    D --> G[spring-boot-starter-security]
    D --> H[spring-boot-starter-webmvc-test]
    D --> I[...]
    
    style A fill:#ffcc99,rx:10,ry:10
    style D fill:#99ff99,rx:10,ry:10
    style E fill:#66ccff,rx:10,ry:10
    style F fill:#66ccff,rx:10,ry:10
    style G fill:#66ccff,rx:10,ry:10
    style H fill:#66ccff,rx:10,ry:10

模块化的优势

  1. 减少应用体积:只引入需要的模块
  2. IDE智能提示优化:不再提示未使用的类和配置
  3. 启动速度提升:减少类扫描范围
  4. 依赖更清晰:明确知道使用了哪些功能

模块使用示例

xml
<!-- 只使用Web MVC功能 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>
<!-- Web MVC测试支持 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webmvc-test</artifactId>
    <scope>test</scope>
</dependency>
<!-- Kotlin序列化支持 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-kotlin-serialization-starter</artifactId>
</dependency>

HTTP客户端增强

RestTemplate废弃计划

Spring Framework 7.1将废弃RestTemplate,推荐使用RestClient接口。Spring Framework 8将完全移除RestTemplate。

mermaid
graph LR
    A[Spring 7.0] --> B[RestTemplate正常使用]
    B --> C[Spring 7.1]
    C --> D[RestTemplate废弃]
    D --> E[Spring 8.0]
    E --> F[RestTemplate移除]
    
    style B fill:#99ff99,rx:10,ry:10
    style D fill:#ffcc99,rx:10,ry:10
    style F fill:#ff9999,rx:10,ry:10

RestClient使用

java
@Configuration
public class HttpClientConfig {
    
    @Bean
    public RestClient restClient(RestClient.Builder builder) {
        return builder
            .baseUrl("http://order-service")
            .defaultHeader("Content-Type", "application/json")
            .requestInterceptor((request, body, execution) -> {
                // 添加认证头
                request.getHeaders().setBearerAuth(getToken());
                return execution.execute(request, body);
            })
            .build();
    }
}

@Service
public class OrderClient {
    
    private final RestClient restClient;
    
    public OrderClient(RestClient restClient) {
        this.restClient = restClient;
    }
    
    public Order getOrder(Long id) {
        return restClient.get()
            .uri("/orders/{id}", id)
            .retrieve()
            .body(Order.class);
    }
    
    public Order createOrder(CreateOrderRequest request) {
        return restClient.post()
            .uri("/orders")
            .body(request)
            .retrieve()
            .body(Order.class);
    }
}

HTTP Interface Groups

新的HTTP Interface Groups允许批量配置HTTP Interface客户端:

java
@Configuration
public class HttpServiceConfig {
    
    @Bean
    public HttpServiceProxyRegistry httpServiceRegistry(RestClient.Builder builder) {
        RestClient sharedClient = builder
            .baseUrl("http://api-gateway")
            .build();
        
        return HttpServiceProxyRegistry.builder()
            .registerGroup("orderServices", config -> {
                config.httpClient(sharedClient);
                config.addInterface(OrderClient.class);
                config.addInterface(OrderItemClient.class);
            })
            .registerGroup("userServices", config -> {
                config.httpClient(sharedClient);
                config.addInterface(UserClient.class);
                config.addInterface(AuthClient.class);
            })
            .build();
    }
}

// 使用注册的接口
@Service
public class OrderService {
    
    private final OrderClient orderClient;
    private final UserClient userClient;
    
    public OrderService(HttpServiceProxyRegistry registry) {
        this.orderClient = registry.getClient(OrderClient.class);
        this.userClient = registry.getClient(UserClient.class);
    }
}

RestTestClient

新增RestTestClient用于非响应式REST测试:

java
@SpringBootTest
@AutoConfigureRestTestClient
class OrderControllerTest {
    
    @Autowired
    private RestTestClient restTestClient;
    
    @Test
    void shouldGetOrder() {
        restTestClient.get()
            .uri("/api/orders/123")
            .exchange()
            .expectStatus().isOk()
            .expectBody(Order.class)
            .value(order -> {
                assertThat(order.getId()).isEqualTo(123L);
                assertThat(order.getStatus()).isEqualTo("CREATED");
            });
    }
    
    @Test
    void shouldCreateOrder() {
        CreateOrderRequest request = new CreateOrderRequest("product-1", 2);
        
        restTestClient.post()
            .uri("/api/orders")
            .bodyValue(request)
            .exchange()
            .expectStatus().isCreated()
            .expectBody(Order.class)
            .value(order -> {
                assertThat(order.getProductId()).isEqualTo("product-1");
            });
    }
}

可观测性增强

OpenTelemetry集成

Spring Boot 4新增spring-boot-starter-opentelemetry,提供开箱即用的OTLP指标和追踪导出:

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-opentelemetry</artifactId>
</dependency>

配置示例

yaml
management:
  otlp:
    metrics:
      export:
        url: http://otel-collector:4318/v1/metrics
    tracing:
      export:
        url: http://otel-collector:4318/v1/traces
  tracing:
    sampling:
      probability: 1.0

SSL健康检查

新增证书过期监控功能:

yaml
management:
  health:
    ssl:
      enabled: true
      certificate-validity-warning-threshold: 30d
  endpoints:
    web:
      exposure:
        include: health

健康检查响应

json
{
  "status": "UP",
  "components": {
    "ssl": {
      "status": "UP",
      "details": {
        "expiringChains": [
          {
            "alias": "server-cert",
            "expiresIn": "25d",
            "expiryDate": "2025-12-15T00:00:00Z"
          }
        ]
      }
    }
  }
}

应用追踪示例

java
@RestController
@RequestMapping("/api/orders")
public class OrderController {
    
    private final OrderService orderService;
    private final ObservationRegistry registry;
    
    @GetMapping("/{id}")
    public Order getOrder(@PathVariable Long id) {
        return Observation.createNotStarted("order.get", registry)
            .lowCardinalityKeyValue("orderId", String.valueOf(id))
            .observe(() -> orderService.findById(id));
    }
}

Spring Data AOT优化

编译时查询生成

Spring Data 2025.1支持在编译时生成仓库查询,显著提升启动速度:

mermaid
graph TB
    A[传统方式] --> B[运行时解析方法名]
    B --> C[动态生成查询]
    C --> D[启动时间长]
    
    E[AOT方式] --> F[编译时解析方法名]
    F --> G[预生成查询代码]
    G --> H[启动时间短]
    
    style A fill:#ffcc99,rx:10,ry:10
    style E fill:#99ff99,rx:10,ry:10
    style D fill:#ff9999,rx:10,ry:10
    style H fill:#99ff99,rx:10,ry:10

性能对比

指标传统JITSpring Data AOT
启动时间3.2秒1.0-1.5秒
提升比例基准50-70%

使用方式

java
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
    
    // 这些方法查询会在编译时生成
    List<Order> findByCustomerId(Long customerId);
    
    List<Order> findByStatusAndCreatedAtAfter(String status, LocalDateTime after);
    
    @Query("SELECT o FROM Order o WHERE o.totalAmount > :amount")
    List<Order> findHighValueOrders(@Param("amount") BigDecimal amount);
}

启用AOT处理

bash
# Maven
mvn spring-boot:process-aot

# Gradle
gradle processAot

其他重要更新

多因素认证

Spring Security 7引入多因素认证支持:

java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        return http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .formLogin(form -> form
                .loginPage("/login")
            )
            .mfa(mfa -> mfa
                .totpEnabled(true)
                .recoveryCodesEnabled(true)
            )
            .build();
    }
}

JMS客户端增强

新增流式JmsClient API:

java
@Service
public class MessageService {
    
    private final JmsClient jmsClient;
    
    public void sendOrder(Order order) {
        jmsClient.send("orders.queue")
            .withMessage(order)
            .withPriority(4)
            .withTimeToLive(Duration.ofMinutes(30))
            .execute();
    }
    
    public Order receiveOrder() {
        return jmsClient.receive("orders.queue")
            .withTimeout(Duration.ofSeconds(10))
            .as(Order.class);
    }
}

Kafka共享消费者

Spring for Apache Kafka 4.0支持Kafka Queues的共享消费者:

java
@Configuration
public class KafkaConfig {
    
    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, Order> 
            shareConsumerFactory(ConsumerFactory<String, Order> cf) {
        ConcurrentKafkaListenerContainerFactory<String, Order> factory = 
            new ConcurrentKafkaListenerContainerFactory<>();
        factory.setConsumerFactory(cf);
        factory.getContainerProperties().setShareConsumer(true);
        return factory;
    }
}

@Service
public class OrderConsumer {
    
    @KafkaListener(
        topics = "orders", 
        containerFactory = "shareConsumerFactory"
    )
    public void processOrder(Order order) {
        // 多个消费者共享分区中的消息
        orderService.process(order);
    }
}

升级迁移指南

升级检查清单

mermaid
graph TB
    A[迁移检查清单] --> B[1. JDK版本确认]
    A --> C[2. 依赖更新]
    A --> D[3. 包名替换]
    A --> E[4. Jackson迁移]
    A --> F[5. 移除废弃API]
    
    B --> G[JDK 17+]
    C --> H[Spring Boot 4.0]
    D --> I[javax → jakarta]
    E --> J[ObjectMapper → JsonMapper]
    F --> K[RestTemplate → RestClient]
    
    style A fill:#66ccff,rx:10,ry:10
    style G fill:#99ff99,rx:10,ry:10
    style H fill:#99ff99,rx:10,ry:10
    style I fill:#99ff99,rx:10,ry:10
    style J fill:#99ff99,rx:10,ry:10
    style K fill:#99ff99,rx:10,ry:10

步骤一:更新依赖

xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>4.0.0</version>
</parent>

步骤二:Jackson迁移

bash
# 全局替换包名
find . -name "*.java" -exec sed -i '' \
  's/com\.fasterxml\.jackson/tools.jackson/g' {} \;

# 替换ObjectMapper为JsonMapper
find . -name "*.java" -exec sed -i '' \
  's/ObjectMapper/JsonMapper/g' {} \;

步骤三:移除废弃API

java
// 移除javax.annotation包
// 旧代码
import javax.annotation.PostConstruct;

// 新代码
import jakarta.annotation.PostConstruct;

// RestTemplate迁移到RestClient
// 旧代码
@Autowired
private RestTemplate restTemplate;

// 新代码
@Autowired
private RestClient restClient;

步骤四:使用OpenRewrite

xml
<plugin>
    <groupId>org.openrewrite.maven</groupId>
    <artifactId>rewrite-maven-plugin</artifactId>
    <version>5.45.0</version>
    <configuration>
        <activeRecipes>
            <recipe>org.openrewrite.java.spring.boot3.UpgradeSpringBoot_4_0</recipe>
        </activeRecipes>
    </configuration>
</plugin>
bash
mvn rewrite:run

常见问题

问题1:Undertow不可用

plain
Caused by: java.lang.UnsupportedOperationException: 
  Undertow is not compatible with Servlet 6.1

解决方案:切换到Tomcat或Jetty

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- 默认使用Tomcat,无需额外配置 -->
</dependency>

问题2:Jackson序列化变化

java
// 如需保持Jackson 2的日期格式
@Configuration
public class JacksonConfig {
    
    @Bean
    public JsonMapper jsonMapper() {
        return JsonMapper.builder()
            .enable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS)
            .disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)
            .build();
    }
}

问题3:JUnit 4不再支持

xml
<!-- 移除JUnit 4 -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
</dependency>
<!-- 使用JUnit 5 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

总结

Spring Boot 4和Spring Framework 7带来了众多革命性的新特性:

mermaid
graph TB
    A[Spring Boot 4 & Spring 7] --> B[API版本控制]
    A --> C[JSpecify空安全]
    A --> D[内置弹性特性]
    A --> E[Jackson 3]
    A --> F[模块化架构]
    A --> G[HTTP客户端增强]
    
    B --> H[规范化API演进]
    C --> I[编译时空检查]
    D --> J[声明式重试/限流]
    E --> K[现代化JSON处理]
    F --> L[按需引入依赖]
    G --> M[RestClient/HTTP Interface]
    
    style A fill:#66ccff,rx:10,ry:10
    style H fill:#99ff99,rx:10,ry:10
    style I fill:#99ff99,rx:10,ry:10
    style J fill:#99ff99,rx:10,ry:10
    style K fill:#99ff99,rx:10,ry:10
    style L fill:#99ff99,rx:10,ry:10
    style M fill:#99ff99,rx:10,ry:10

这次升级标志着Spring生态系统向更现代化、更云原生的方向迈进,为Java开发者提供了更强大的工具和更优雅的开发体验。

更新: 2025-12-05 16:01:29
原文: https://www.yuque.com/u22210564/zoxfmt/ac612xsza02msfod

Java 后端面试知识库