Spring Boot 4.0新特性

lijunyi2025-05-10javaspringBoot

Spring Boot 4.0新特性

一、接口版本控制

@RequestMapping 新增 version 参数,实现接口多版本共存。

@RestController
@RequestMapping("/api")
publicclass VersionedController {

    @RequestMapping(value = "/user", version = "1")
    public String getUserV1() {
        return"Version 1 - 接口 1";
    }

    @RequestMapping(value = "/user", version = "2")
    public String getUserV2() {
        return"Version 2 - 接口 2";
    }
}

还可以通过实现 WebMvcConfigurer 接口并重写 configureApiVersioning 方法,自定义版本解析策略:

@Configuration
publicclass WebConfiguration implements WebMvcConfigurer {
    @Override
    public void configureApiVersioning(ApiVersionConfigurer configurer) {
        // 方式1:用请求参数 (默认参数名 "version"),比如 /api/users?version=1
        configurer.useRequestParam("version");

        // 方式2:用请求头,比如 Header里加 API-Version: 1
        // configurer.useRequestHeader("API-Version");

        // 方式3:用路径变量,比如 /api/v1/users
        // configurer.usePathVariable("version");

    }
}

新的 Bean 注入机制

通过实现 BeanRegistrar 接口,你可以自定义 Bean 的注册策略:

@Configuration
@Import(MyBeansRegistrar.class)
public class MyConfiguration {
}

class MyBeansRegistrar implements BeanRegistrar {
    @Override
    public void register(BeanRegistry registry, Environment env) {
        registry.registerBean("user", User.class); // 常规操作

        if (env.matchesProfiles("dev")) { // 开发环境,来点不一样的
            registry.registerBean(Order.class, spec -> spec
                    .supplier(context -> new Order("order_dev_001")));
        }
    }
}

虚拟线程支持

基于 JDK 21 提供的虚拟线程特性,Spring Boot 4.0 对线程池模型进行了重构,支持实现百万级并发。在支付网关场景测试中,虚拟线程的应用使每秒请求处理量(RPS)从 1.2 万提升至 8.5 万,同时 CPU 占用率下降了 40%。

我们只需通过简单配置 spring.threads.virtual.enabled=true 即可全局启用虚拟线程. 且原有的 @Async 注解也能无缝适配,无需额外改动代码。此外,为了便于监控,Actuator 引入了 /virtual-threads 端点,可以通过该端点实时查看线程状态与阻塞事件。

JSpecify

JSpecify 是一套注解、规范和文档,旨在借助 NullAway 等工具,确保 IDE 或编译过程中 Java 应用和库的 null safety。

public class Person {
    private String name;

    public void setName(@NonNull String name) { // 明确告诉这name不传null
        this.name = name;
    }

    @Nullable
    public String getName() {
        return this.name;
    }
}
Last Updated 2025/6/10 15:56:40