📅 发布日期:2025年11月20日
🎯 适合人群:有 Spring Boot 3.x 基础的开发者
| 工具 | 最低版本 | 推荐版本 | 说明 |
|---|---|---|---|
| Java | 17 | 21 | 推荐21以使用虚拟线程 |
| Maven | 3.6 | 3.9+ | 或使用 Gradle 9 |
| IDE | - | IntelliJ IDEA 2024+ | 需要支持 Java 21 |
# 检查 Java 版本
java -version
# 应显示: openjdk version "21.x.x" 或更高
# 检查 Maven 版本
mvn -version
# 应显示: Apache Maven 3.9.x 或更高方式一:使用 Spring Initializr
- 访问 https://start.spring.io
- 选择 Spring Boot 4.0.0
- 选择 Java 21
- 添加依赖:Web, Actuator
方式二:使用本演示项目
cd d:\code\hd-backend\spring-boot4-demo
mvn clean install# 方式一:Maven 运行
mvn spring-boot:run
# 方式二:打包后运行
mvn clean package
java -jar target/spring-boot4-demo.jar启动后访问 http://localhost:8090 查看所有演示接口:
# 查看首页(所有接口列表)
curl http://localhost:8090/
# 测试 API 版本控制
curl http://localhost:8090/api/v1/users
curl http://localhost:8090/api/v2/users
# 测试 HTTP Service Client
curl http://localhost:8090/github/users/spring-projects
# 测试可观测性
curl http://localhost:8090/observability/auto-trace声明式 HTTP 客户端,类似于 OpenFeign,但是 Spring 原生支持,无需额外依赖。
- ✅ 无需手动编写 RestTemplate/WebClient 调用代码
- ✅ 接口定义清晰,易于维护
- ✅ Spring 原生,与生态深度集成
第一步:定义接口
// 文件:feature1_http_service/GitHubService.java
@HttpExchange(url = "https://api.github.com")
public interface GitHubService {
// GET 请求
@GetExchange("/users/{username}")
Map<String, Object> getUser(@PathVariable String username);
// POST 请求
@PostExchange("/repos")
Map<String, Object> createRepo(@RequestBody Map<String, String> repo);
// 带请求头
@GetExchange("/user")
Map<String, Object> getCurrentUser(@RequestHeader("Authorization") String token);
}第二步:配置代理
// 文件:feature1_http_service/HttpServiceConfig.java
@Configuration
public class HttpServiceConfig {
@Bean
public GitHubService gitHubService() {
RestClient restClient = RestClient.builder()
.baseUrl("https://api.github.com")
.defaultHeader("User-Agent", "My-App")
.build();
HttpServiceProxyFactory factory = HttpServiceProxyFactory
.builderFor(RestClientAdapter.create(restClient))
.build();
return factory.createClient(GitHubService.class);
}
}第三步:注入使用
@RestController
@RequiredArgsConstructor
public class MyController {
private final GitHubService gitHubService;
@GetMapping("/user/{name}")
public Map<String, Object> getUser(@PathVariable String name) {
return gitHubService.getUser(name); // 直接调用接口方法
}
}| 注解 | 说明 | 示例 |
|---|---|---|
@HttpExchange |
定义基础URL | @HttpExchange(url = "https://api.example.com") |
@GetExchange |
GET 请求 | @GetExchange("/users") |
@PostExchange |
POST 请求 | @PostExchange("/users") |
@PutExchange |
PUT 请求 | @PutExchange("/users/{id}") |
@DeleteExchange |
DELETE 请求 | @DeleteExchange("/users/{id}") |
@PatchExchange |
PATCH 请求 | @PatchExchange("/users/{id}") |
内置的 API 版本控制支持,无需手动实现。
- ✅ 标准化的版本控制方案
- ✅ 支持多种版本传递方式
- ✅ 配置简单,开箱即用
第一步:启用配置
# application.yml
spring:
mvc:
apiversion:
enabled: true
parameter-name: v # 参数名:?v=1.0
header-name: X-API-Version # 请求头名
default-version: 1.0 # 默认版本第二步:编写多版本接口
// 文件:feature2_api_versioning/ApiVersioningController.java
@RestController
@RequestMapping("/api")
public class ApiVersioningController {
// V1 版本 - 简单数据
@GetMapping("/v1/users")
public Map<String, Object> getUsersV1() {
return Map.of(
"version", "1.0",
"users", List.of("张三", "李四")
);
}
// V2 版本 - 详细数据
@GetMapping("/v2/users")
public Map<String, Object> getUsersV2() {
return Map.of(
"version", "2.0",
"users", List.of(
Map.of("id", 1, "name", "张三", "email", "zs@example.com"),
Map.of("id", 2, "name", "李四", "email", "ls@example.com")
)
);
}
}第三步:客户端调用
# 方式1:URL路径
curl http://localhost:8090/api/v1/users
curl http://localhost:8090/api/v2/users
# 方式2:请求参数
curl "http://localhost:8090/api/users?v=1.0"
curl "http://localhost:8090/api/users?v=2.0"
# 方式3:请求头
curl -H "X-API-Version: 1.0" http://localhost:8090/api/users
curl -H "X-API-Version: 2.0" http://localhost:8090/api/users一站式可观测性支持,自动配置 Metrics(指标)和 Traces(追踪)。
- ✅ 无需手动集成 OpenTelemetry SDK
- ✅ 自动为 HTTP 请求创建 Span
- ✅ 支持 OTLP 协议导出到 Jaeger、Zipkin 等
第一步:添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-opentelemetry</artifactId>
</dependency>第二步:配置导出端点
# application.yml
management:
tracing:
sampling:
probability: 1.0 # 采样率 100%
otlp:
tracing:
endpoint: http://localhost:4318/v1/traces
metrics:
endpoint: http://localhost:4318/v1/metrics第三步:自动追踪生效
所有 HTTP 请求自动创建 Span,无需额外代码!
第四步:手动创建 Observation(可选)
// 文件:feature3_opentelemetry/ObservabilityController.java
@RestController
@RequiredArgsConstructor
public class ObservabilityController {
private final ObservationRegistry observationRegistry;
@GetMapping("/my-operation")
public String myOperation() {
return Observation.createNotStarted("my.custom.operation", observationRegistry)
.lowCardinalityKeyValue("type", "demo")
.observe(() -> {
// 你的业务逻辑
return "操作完成";
});
}
}支持多个 TaskDecorator,自动组合成 CompositeTaskDecorator。
- ✅ 关注点分离:日志、MDC、指标各自独立
- ✅ 按
@Order顺序执行 - ✅ 易于扩展和维护
第一步:创建多个装饰器
// 装饰器1:日志记录(最先执行)
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class LoggingTaskDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
return () -> {
log.info("任务开始");
runnable.run();
log.info("任务结束");
};
}
}
// 装饰器2:MDC上下文传递
@Component
@Order(0)
public class MdcTaskDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
Map<String, String> context = MDC.getCopyOfContextMap();
return () -> {
if (context != null) MDC.setContextMap(context);
try {
runnable.run();
} finally {
MDC.clear();
}
};
}
}
// 装饰器3:指标收集(最后执行,最接近实际任务)
@Component
@Order(1)
public class MetricsTaskDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
return () -> {
Timer.Sample sample = Timer.start();
try {
runnable.run();
} finally {
sample.stop(taskTimer);
}
};
}
}第二步:启用异步
@Configuration
@EnableAsync
public class AsyncConfig {
// Spring Boot 4.0 自动组合所有 TaskDecorator
}第三步:使用异步方法
@Service
public class MyService {
@Async
public CompletableFuture<String> asyncTask() {
// 这个任务会被所有装饰器包装
return CompletableFuture.completedFuture("完成");
}
}执行顺序:
LoggingTaskDecorator (Order=HIGHEST)
└─> MdcTaskDecorator (Order=0)
└─> MetricsTaskDecorator (Order=1)
└─> 实际任务
新的测试客户端,提供流式 API,更简洁的测试代码。
- ✅ 流式 API,代码更简洁
- ✅ 更好的断言支持
- ✅ 与 AssertJ 深度集成
// 文件:test/.../Feature5RestTestClientTest.java
@SpringBootTest
@AutoConfigureMockMvc
class MyTest {
@Autowired
private MockMvcTester mockMvc; // 新的测试客户端
@Test
void testGetUsers() {
mockMvc.get().uri("/api/v1/users")
.assertThat()
.hasStatusOk() // 断言状态码
.bodyJson()
.extractingPath("$.version") // 提取 JSON 字段
.isEqualTo("1.0"); // 断言值
}
@Test
void testPostUser() {
mockMvc.post().uri("/api/users")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"name\": \"张三\"}")
.assertThat()
.hasStatus(HttpStatus.CREATED)
.bodyJson()
.extractingPath("$.id")
.isNotNull();
}
@Test
void testWithHeader() {
mockMvc.get().uri("/api/users")
.header("X-API-Version", "2.0")
.assertThat()
.hasStatusOk();
}
}使用 HTTP Service Client 调用天气 API:
@HttpExchange(url = "https://api.weatherapi.com/v1")
public interface WeatherService {
@GetExchange("/current.json")
Map<String, Object> getCurrentWeather(
@RequestParam("key") String apiKey,
@RequestParam("q") String city
);
}创建 V1、V2、V3 三个版本的用户接口,逐步增加返回字段。
创建一个 SecurityContextTaskDecorator,在异步任务中传递安全上下文。
第一步:升级到 3.5
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.0</version>
</parent>第二步:升级 Java 版本
<properties>
<java.version>21</java.version>
</properties>第三步:升级到 4.0
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.0</version>
</parent>第四步:检查废弃 API
参考官方迁移指南: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0-Migration-Guide
Spring Boot 4.0 基于 Spring Framework 7.0,要求 Java 17+。推荐 Java 21 是因为:
- 虚拟线程(Virtual Threads)正式发布
- 更好的性能和内存管理
可以,但推荐使用原生的 HTTP Service Client:
- 无需额外依赖
- 与 Spring 生态更好集成
- 支持响应式编程
Spring Boot 4.0 中:
- Micrometer 是抽象层(Observation API)
- OpenTelemetry 是具体实现
- 两者深度集成,可以同时使用
修改 pom.xml 中的 parent 版本即可:
<version>3.5.0</version>- Spring Boot 4.0 Release Notes
- Spring Boot 4.0 Migration Guide
- Spring Framework 7.0 文档
- OpenTelemetry 官方文档
💡 提示:遇到问题可以在 Stack Overflow 搜索
spring-boot标签。
祝学习愉快! 🎉