- Spring Boot 3 到 4 迁移完全指南:新特性、废弃功能与实战踩坑经验
2025 年 11 月,Spring Boot 4.0 正式发布,这次升级被业界称为爆炸性升级。同时对于云原生应用而言,这是一次不可错过的性能与效率跃迁:
但这次升级也带来了 36 个废弃 API 移除、模块化架构重构、Tomcat 11 变更等挑战。本文基于 Spring Boot 官方文档和生产环境迁移经验,从原理到踩坑,提供完整、实用的迁移指南,助你平稳完成云原生应用的升级。
作为 Spring Boot 3.x 之后的首个大版本更新,Spring Boot 4.0 基于 Spring Framework 7.0、Jakarta EE 11 和 Java 17+(推荐 Java 21 或 25),带来了模块化架构重构、虚拟线程原生支持、HTTP 服务客户端自动配置等重大变化。
Spring Boot 4.0 配套使用 Spring Cloud 2025.1.x。虽然版本号看起来只是中号版本变更,但实际上这是一次大版本变更,包含了大量破坏性变更和重要更新。
Spring Boot 4 将 spring-boot-autoconfigure 拆分为多个专注的模块,每个技术都有独立的 starter 和对应的测试 starter。
主要变化:
spring-boot-<technology>,包路径:org.springframework.boot.<technology>spring-boot-starter-<technology> 和 spring-boot-starter-<technology>-test模块化的优势:
spring-boot-autoconfigure 是 2 MiB,模块化后只引入需要的模块,显著减少占用WebClient(通过 spring-boot-starter-webclient),不会意外启用 Web 服务器自动配置,不再需要调用 SpringApplication.setWebApplicationType(WebApplicationType.NONE)spring-boot-starter-micrometer-metrics),而不需要完整的 Actuator 依赖链测试支持的模块化:
spring-boot-test-autoconfigure 也被模块化了。测试相关的注解现在位于对应的测试模块中。例如,@AutoConfigureDataJdbc 注解现在位于 spring-boot-starter-data-jdbc-test 模块中,与 spring-boot-starter-data-jdbc 对齐。
测试 Starter 的传递性:
所有 test starter 都会传递性地引入 spring-boot-starter-test,因此不需要再单独声明 spring-boot-starter-test。只需要列出被测试技术对应的 test starter 即可。
主要废弃 Starter 和替代方案:
| 废弃 Starter | 替代 |
|---|---|
spring-boot-starter-web | spring-boot-starter-webmvc |
spring-boot-starter-aop | spring-boot-starter-aspectj |
spring-boot-starter-oauth2-authorization-server | spring-boot-starter-security-oauth2-authorization-server |
spring-boot-starter-oauth2-client | spring-boot-starter-security-oauth2-client |
spring-boot-starter-oauth2-resource-server | spring-boot-starter-security-oauth2-resource-server |
spring-boot-starter-web-services | spring-boot-starter-webservices |
其他迁移要点:
-test starter,如 spring-boot-starter-security-test完整的 Starter 列表:
Spring Boot 4.0 统一了 starter 的使用方式:大多数技术都有专门的 starter,每个 starter 都有对应的 test starter。以下是完整的列表(参考 官方迁移指南 ):
| Technology | Main Dependency | Test Dependency |
|---|---|---|
| Core Starters | ||
| AspectJ | spring-boot-starter-aspectj | spring-boot-starter-aspectj-test |
| Cloud Foundry Support | spring-boot-starter-cloudfoundry | spring-boot-starter-cloudfoundry-test |
| Jakarta Validation | spring-boot-starter-validation | spring-boot-starter-validation-test |
| Kotlin Serialization | spring-boot-starter-kotlin-serialization | spring-boot-starter-kotlin-serialization-test |
| Reactor | spring-boot-starter-reactor | spring-boot-starter-reactor-test |
| Web Server Starters | ||
| Jetty | spring-boot-starter-jetty | none |
| Reactor Netty | spring-boot-starter-reactor-netty | none |
| Tomcat | spring-boot-starter-tomcat | none |
| Web Client Starters | ||
Spring’s Imperative RestClient and RestTemplate | spring-boot-starter-restclient | spring-boot-starter-restclient-test |
Spring’s Reactive WebClient | spring-boot-starter-webclient | spring-boot-starter-webclient-test |
| Web Starters | ||
| Jersey | spring-boot-starter-jersey | spring-boot-starter-jersey-test |
| Spring GraphQL | spring-boot-starter-graphql | spring-boot-starter-graphql-test |
| Spring HATEOAS | spring-boot-starter-hateoas | spring-boot-starter-hateoas-test |
| Spring Session Data Redis | spring-boot-starter-session-data-redis | spring-boot-starter-session-data-redis-test |
| Spring Session JDBC | spring-boot-starter-session-jdbc | spring-boot-starter-session-jdbc-test |
| Spring Web MVC | spring-boot-starter-webmvc | spring-boot-starter-webmvc-test |
| Spring WebFlux | spring-boot-starter-webflux | spring-boot-starter-webflux-test |
| Spring Webservices | spring-boot-starter-webservices | spring-boot-starter-webservices-test |
| Database Starters | ||
| Cassandra | spring-boot-starter-cassandra | spring-boot-starter-cassandra-test |
| Couchbase | spring-boot-starter-couchbase | spring-boot-starter-couchbase-test |
| Elasticsearch | spring-boot-starter-elasticsearch | spring-boot-starter-elasticsearch-test |
| Flyway | spring-boot-starter-flyway | spring-boot-starter-flyway-test |
| JDBC | spring-boot-starter-jdbc | spring-boot-starter-jdbc-test |
| jOOQ | spring-boot-starter-jooq | spring-boot-starter-jooq-test |
| Liquibase | spring-boot-starter-liquibase | spring-boot-starter-liquibase-test |
| LDAP | spring-boot-starter-ldap | spring-boot-starter-ldap-test |
| MongoDB | spring-boot-starter-mongodb | spring-boot-starter-mongodb-test |
| Neo4J | spring-boot-starter-neo4j | spring-boot-starter-neo4j-test |
| R2DBC | spring-boot-starter-r2dbc | spring-boot-starter-r2dbc-test |
| Spring Data Starters | ||
| Spring Data Cassandra | spring-boot-starter-data-cassandra 或 spring-boot-starter-data-cassandra-reactive | spring-boot-starter-data-cassandra-test 或 spring-boot-starter-data-cassandra-reactive-test |
| Spring Data Couchbase | spring-boot-starter-data-couchbase 或 spring-boot-starter-data-couchbase-reactive | spring-boot-starter-data-couchbase-test 或 spring-boot-starter-data-couchbase-reactive-test |
| Spring Data Elasticsearch | spring-boot-starter-data-elasticsearch | spring-boot-starter-data-elasticsearch-test |
| Spring Data JDBC | spring-boot-starter-data-jdbc | spring-boot-starter-data-jdbc-test |
| Spring Data JPA (using Hibernate) | spring-boot-starter-data-jpa | spring-boot-starter-data-jpa-test |
| Spring Data LDAP | spring-boot-starter-data-ldap | spring-boot-starter-data-ldap-test |
| Spring Data MongoDB | spring-boot-starter-data-mongodb 或 spring-boot-starter-data-mongodb-reactive | spring-boot-starter-data-mongodb-test 或 spring-boot-starter-data-mongodb-reactive-test |
| Spring Data Neo4J | spring-boot-starter-data-neo4j | spring-boot-starter-data-neo4j-test |
| Spring Data R2DBC | spring-boot-starter-data-r2dbc | spring-boot-starter-data-r2dbc-test |
| Spring Data Redis | spring-boot-starter-data-redis 或 spring-boot-starter-data-redis-reactive | spring-boot-starter-data-redis-test 或 spring-boot-starter-data-redis-reactive-test |
| Spring Data REST | spring-boot-starter-data-rest | spring-boot-starter-data-rest-test |
| IO Starters | ||
| Hazelcast | spring-boot-starter-hazelcast | spring-boot-starter-hazelcast-test |
spring-boot-starter-mail | spring-boot-starter-mail-test | |
| Quartz | spring-boot-starter-quartz | spring-boot-starter-quartz-test |
| SendGrid | spring-boot-starter-sendgrid | spring-boot-starter-sendgrid-test |
| Spring Caching Support | spring-boot-starter-cache | spring-boot-starter-cache-test |
| Spring Batch (with JDBC) | spring-boot-starter-batch-jdbc | spring-boot-starter-batch-jdbc-test |
| Spring Batch (without JDBC) | spring-boot-starter-batch | spring-boot-starter-batch-test |
| JSON Starters | ||
| GSON | spring-boot-starter-gson | spring-boot-starter-gson-test |
| Jackson | spring-boot-starter-jackson | spring-boot-starter-jackson-test |
| JSONB | spring-boot-starter-jsonb | spring-boot-starter-jsonb-test |
| Messaging Starters | ||
| ActiveMQ | spring-boot-starter-activemq | spring-boot-starter-activemq-test |
| Artemis | spring-boot-starter-artemis | spring-boot-starter-artemis-test |
| JMS | spring-boot-starter-jms | spring-boot-starter-jms-test |
| RSocket | spring-boot-starter-rsocket | spring-boot-starter-rsocket-test |
| Spring AMQP | spring-boot-starter-amqp | spring-boot-starter-amqp-test |
| Spring Integration | spring-boot-starter-integration | spring-boot-starter-integration-test |
| Spring for Apache Kafka | spring-boot-starter-kafka | spring-boot-starter-kafka-test |
| Spring for Apache Pulsar | spring-boot-starter-pulsar | spring-boot-starter-pulsar-test |
| Websockets | spring-boot-starter-websocket | spring-boot-starter-websocket-test |
| Security Starters | ||
| Spring Security | spring-boot-starter-security | spring-boot-starter-security-test |
| Spring Security OAuth Authorization Server | spring-boot-starter-security-oauth2-authorization-server | spring-boot-starter-security-oauth2-authorization-server-test |
| Spring Security OAuth Client | spring-boot-starter-security-oauth2-client | spring-boot-starter-security-oauth2-client-test |
| Spring Security OAuth Resource Server | spring-boot-starter-security-oauth2-resource-server | spring-boot-starter-security-oauth2-resource-server-test |
| Spring Security SAML | spring-boot-starter-security-saml2 | spring-boot-starter-security-saml2-test |
| Templating Starters | ||
| Freemarker | spring-boot-starter-freemarker | spring-boot-starter-freemarker-test |
| Groovy Templates | spring-boot-starter-groovy-templates | spring-boot-starter-groovy-templates-test |
| Mustache | spring-boot-starter-mustache | spring-boot-starter-mustache-test |
| Thymeleaf | spring-boot-starter-thymeleaf | spring-boot-starter-thymeleaf-test |
| Production-Ready Starters | ||
| Actuator | spring-boot-starter-actuator | spring-boot-starter-actuator-test |
| Micrometer Metrics | spring-boot-starter-micrometer-metrics | spring-boot-starter-micrometer-metrics-test |
| OpenTelemetry | spring-boot-starter-opentelemetry | spring-boot-starter-opentelemetry-test |
| Zipkin | spring-boot-starter-zipkin | spring-boot-starter-zipkin-test |
提示: 所有 test starter 都会传递性地引入
spring-boot-starter-test,因此不需要再单独声明spring-boot-starter-test。只需要列出被测试技术对应的 test starter 即可。
Classic Starters(快速迁移方案):
如果需要快速迁移,可以使用 Classic Starters,它们提供了类似 Spring Boot 3.x 的 classpath,让你可以快速恢复所有基础设施的可用性:
<!-- 替代 spring-boot-starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-classic</artifactId>
</dependency>
<!-- 替代 spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test-classic</artifactId>
<scope>test</scope>
</dependency>使用 Classic Starters 的好处:
迁移建议(官方推荐的两步法):
注意: 官方建议最终还是要迁移到模块化的 starter,Classic Starters 只是过渡方案。完整的 starter 列表和对应关系请参考 官方迁移指南 。
Spring Boot 4 引入了新的注解 @ConfigurationPropertiesSource,允许 Spring Boot 读取外部模块中定义的 @ConfigurationProperties 类型,这在之前是不可能的。
使用场景:
@ConfigurationPropertiesSource("com.example.config")
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
// getters and setters
}优势:
Spring Boot 4 现在支持配置多个 TaskDecorator Bean,允许你组合多个装饰器来增强任务执行行为。
使用示例:
@Configuration
public class TaskConfig {
@Bean
public TaskDecorator loggingTaskDecorator() {
return runnable -> {
return () -> {
System.out.println("Task started: " + Thread.currentThread().getName());
try {
runnable.run();
} finally {
System.out.println("Task completed");
}
};
};
}
@Bean
public TaskDecorator mdcTaskDecorator() {
return runnable -> {
String traceId = MDC.get("traceId");
return () -> {
MDC.put("traceId", traceId);
try {
runnable.run();
} finally {
MDC.clear();
}
};
};
}
}多个 TaskDecorator 会按顺序应用,提供更灵活的任务执行增强能力。
模块化架构对包结构也有影响。每个模块现在都有独立的 org.springframework.boot.<module> 包路径。根据模块的职责范围,可能包含 API、自动配置、Actuator 相关支持等。
示例:
// Spring Boot 3.x
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
// Spring Boot 4.0
import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration;主要变化:
org.springframework.boot.<technology>org.springframework.boot.<technology>.testSpring Boot 4 基于 Spring Framework 7.0 构建,继承了以下特性。
Spring Framework 7 原生支持 API 版本管理,这是首次在 Spring 框架中提供官方支持。之前虽然可以通过 @RequestMapping 实现,但需要大量手动工作。
配置方式:
Java 配置:
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void configureApiVersioning(ApiVersionConfigurer configurer) {
configurer.useRequestHeader("API-Version");
// 或使用其他策略:
// configurer.useQueryParameter("version");
// configurer.usePathPattern("/api/{version}");
// configurer.useMediaType("application/vnd.api.v1+json");
}
}Spring Boot 配置属性:
spring:
mvc:
apiversion:
use:
header: API-Version
# 或使用:
# query-parameter: version
# path-pattern: /api/{version}使用示例:
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping(value = "/users", version = "1")
public List<UserV1> getUsersV1() {
return userService.getUsersV1();
}
@GetMapping(value = "/users", version = "2")
public List<UserV2> getUsersV2() {
return userService.getUsersV2();
}
}功能式端点支持:
RouterFunction<ServerResponse> route = RouterFunctions.route()
.GET("/hello-world", version("1.2"),
request -> ServerResponse.ok().body("Hello World"))
.build();支持的版本控制策略:
/v1/users、/v2/users(需要在路径中声明 URI 变量)X-API-Version: 1 或自定义 header 名称/users?version=1Accept: application/vnd.api.v1+json版本格式:
默认使用语义化版本(Semantic Versioning),支持 major.minor.patch 格式。如果未指定 minor 和 patch,默认为 0。版本解析器可以自定义,支持日期格式或其他格式。
废弃处理:
API 版本控制支持 RFC 9745 标准的废弃处理,可以在响应中发送废弃提示。
Spring Framework 7 迁移到 JSpecify 注解,这是 Spring 生态系统中空安全支持的重大里程碑。JSpecify 是一个由 OpenJDK、Broadcom、Google、JetBrains、Sonar 等组织共同参与的标准项目。
已支持 JSpecify 的 Spring 项目:
使用示例:
import org.jspecify.annotations.Nullable;
import org.jspecify.annotations.NonNull;
public class UserService {
public @NonNull User getUser(@NonNull String userId) {
return userRepository.findById(userId)
.orElseThrow(() -> new UserNotFoundException(userId));
}
public @Nullable User findUser(@NonNull String email) {
return userRepository.findByEmail(email).orElse(null);
}
}IDE 支持:
Kotlin 项目注意事项:
JSpecify 注解会明确标记可空性,Kotlin 编译器会自动识别并转换。如果 Java 接口使用 @Nullable 注解,Kotlin 实现必须返回可空类型;如果使用 @NonNull,则必须返回非空类型。IntelliJ IDEA 会提供相应的编译错误提示和修复建议。
Spring Framework 7.0 引入了多线程异步启动机制,可以并行初始化 ApplicationContext,显著加快应用启动速度。
工作原理:
配置方式:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
// 启用异步启动
app.setApplicationStartup(new BufferingApplicationStartup(1000));
app.run(args);
}
}或者通过配置属性:
spring:
application:
startup:
enabled: true性能提升:
注意事项:
Spring Framework 7 和 Spring Boot 4 大幅简化了 HTTP 接口客户端的配置。之前需要手动创建 HttpServiceProxyFactory 和配置每个客户端,现在可以通过声明式方式自动注册。
建议: 虽然 RestTemplate 仍可使用,但推荐使用 RestClient 或 HTTP 接口客户端(@HttpExchange)作为替代方案。
旧方式(Spring Framework 6 / Spring Boot 3):
@HttpExchange(url = "/api/users")
public interface UserClient {
@GetExchange("/{id}")
User getUser(@PathVariable String id);
@PostExchange
User createUser(@RequestBody UserRequest request);
}
// 需要手动配置每个客户端
@Configuration
public class HttpClientConfig {
@Bean
public UserClient userClient(RestClient.Builder builder) {
RestClient restClient = builder.baseUrl("https://api.example.com").build();
HttpServiceProxyFactory factory = HttpServiceProxyFactory
.builderFor(RestClientAdapter.create(restClient)).build();
return factory.createClient(UserClient.class);
}
// 如果有多个客户端,需要重复配置。..
}新方式(Spring Framework 7 / Spring Boot 4):
使用 @ImportHttpServices 注解:
@HttpExchange(url = "/api/users")
public interface UserClient {
@GetExchange("/{id}")
User getUser(@PathVariable String id);
@PostExchange
User createUser(@RequestBody UserRequest request);
}
@Configuration
@ImportHttpServices(group = "api", types = {UserClient.class})
public class HttpClientConfig {
}配置 application.yml:
spring:
http:
client:
service:
read-timeout: 2s
group:
api:
base-url: https://api.example.com或使用包扫描自动发现:
@Configuration
@ImportHttpServices(group = "api", basePackages = "com.example.client")
public class HttpClientConfig {
}多组配置示例:
如果应用需要集成多个 REST API,可以为每个 API 配置不同的组:
@Configuration
@ImportHttpServices(group = "github", basePackages = "com.example.client.github")
@ImportHttpServices(group = "stackoverflow", basePackages = "com.example.client.stackoverflow")
public class HttpClientConfig {
}对应的配置:
spring:
http:
client:
service:
group:
github:
base-url: https://api.github.com
read-timeout: 5s
stackoverflow:
base-url: https://api.stackexchange.com
read-timeout: 10s使用 WebClient(响应式):
默认使用 RestClient,如需使用 WebClient,可通过配置切换:
@Configuration
@ImportHttpServices(
group = "api",
basePackages = "com.example.client",
clientType = ClientType.WEB_CLIENT
)
public class HttpClientConfig {
}优势:
HttpServiceProxyFactory 和 Bean这样 com.example.client 包下所有带 @HttpExchange 的接口都会自动注册为 Spring Bean,可以直接注入使用:
@Service
public class UserService {
private final UserClient userClient; // 直接注入,无需手动配置
public UserService(UserClient userClient) {
this.userClient = userClient;
}
public User getUser(String id) {
return userClient.getUser(id); // 直接使用
}
}Spring Framework 7 引入了强大的弹性工具,直接集成到核心框架中:
配置方式:
@Configuration
@EnableResilientMethods
public class ApplicationConfig {
}
@Service
public class PaymentService {
@Retryable(
maxAttempts = 3,
backoff = @Retryable.Backoff(delay = 2000, multiplier = 2.0)
)
@ConcurrencyLimit(value = 2) // 只允许 2 个并发调用
public void processPayment(String paymentId) {
// 处理支付逻辑
}
}优势:
Spring Framework 7 引入了 JmsClient,类似于 JdbcClient 和 RestClient,提供流畅的构建器风格 API。这是对传统 JMS 模板的更优雅和可读的替代方案。
使用示例:
@Service
public class MessageService {
private final JmsClient jmsClient;
public MessageService(JmsClient jmsClient) {
this.jmsClient = jmsClient;
}
public void sendMessage(String destination, String message) {
jmsClient.create()
.queue(destination)
.body(message)
.send();
}
public String receiveMessage(String destination) {
return jmsClient.create()
.queue(destination)
.receive(String.class);
}
}优势:
JdbcClient、RestClient 保持一致的风格Spring Framework 7 简化了消息转换,引入了新的 HttpMessageConverters 配置类。这种统一方法借鉴了响应式编解码器的设计,简化了 HTTP 消息的序列化和反序列化。
Spring Framework 7 采用 Jakarta EE 11 规范:
JPA 3.2 重要变化:
之前,EntityManager 只能通过 @PersistenceContext 注解注入。现在,EntityManagerFactory 和共享的 EntityManager 都可以使用 @Inject 或 @Autowired 注入,并支持使用限定符来选择特定的持久化单元(当配置了多个持久化单元时)。
// 旧方式(仍然支持)
@PersistenceContext
private EntityManager entityManager;
// 新方式(Spring Framework 7 / JPA 3.2)
@Autowired
private EntityManager entityManager;
// 多个持久化单元时使用限定符
@Autowired
@Qualifier("primaryEntityManager")
private EntityManager primaryEntityManager;这里要提醒一下:javax.* 到 jakarta.* 的迁移应该在 Spring Boot 3.0 的时候就已经完成了。如果你还在用 Spring Boot 2.x,那得先升级到 3.x,然后再考虑 4.0。
Jackson 3.x 的破坏性变更:
ObjectMapper 行为变更迁移示例:
// Jackson 2.x
@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
private String name;
// ...
}
// Jackson 3.x (同样的语法,但内部行为可能不同)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
private String name;
// ...
}Spring Framework 7 引入了一个挺有意思的测试上下文管理机制:
该机制可显著降低测试套件的内存占用。
支持 Optional 类型和 Elvis 操作符:
@Value("#{userService.findUser('123')?.name ?: 'Unknown'}")
private String userName;Spring Framework 7 引入了 BeanRegistrar 接口,允许在 @ConditionalOn... 注解族不够用时进行动态 Bean 注册。
Java 实现:
import org.springframework.context.bean.BeanRegistrar;
import org.springframework.context.bean.BeanRegistry;
public class QuoteProviderRegistrar implements BeanRegistrar {
@Override
public void register(BeanRegistry registry, Environment env) {
registry.registerBean("quoteProviderDb", QuoteProviderDb.class);
registry.registerBean("quoteProviderFallback",
QuoteProviderFallback.class,
spec -> {
spec.fallback();
spec.order(1);
});
}
}Kotlin DSL 实现(更优雅):
Kotlin 2.2 提供了 BeanRegistrarDsl,让 Bean 注册更加简洁:
import org.springframework.context.bean.BeanRegistrarDsl
class QuoteProviderRegistrar : BeanRegistrarDsl({
registerBean<QuoteProviderDb>("quoteProviderDb")
registerBean<QuoteProviderFallback>(
name = "quoteProviderFallback",
fallback = true,
order = 1
)
})使用场景:
@ConditionalOn... 注解的能力范围Tomcat 11 是 Apache Tomcat 项目第九个主要版本,标志着从传统 Java EE 向现代 Jakarta EE 框架的重要转变。本次升级支持 Jakarta EE 11,实现了:
重要特性: Tomcat 11 原生支持 Java 21 的 Project Loom 虚拟线程,这是本次升级的核心亮点之一。
性能数据(基于实际测试):
根据 Fast Thread 和 Java Code Geeks 的性能基准测试:
| 场景 | 平台线程 | 虚拟线程 | 性能提升 |
|---|---|---|---|
| I/O 密集型应用(数据库查询、HTTP 调用) | 基准 | 2-3x 吞吐量 | +100-200% |
| 高并发 Web 请求(1000+ 并发) | 基准 | 2-3x 吞吐量 | +100-200% |
| CPU 密集型应用 | 基准 | 无明显提升 | 0% |
| 内存占用 | 基准 | -30-50%(线程栈) | -30-50% |
| 响应时间(P99) | 基准 | -20-40% | -20-40% |
适用场景:
实际案例:
一个典型的 Spring Boot Web 应用(处理 REST 请求,调用数据库和外部 API):
优势:
配置方式:
在 Spring Boot 4 中,虚拟线程支持通过配置属性启用:
spring:
threads:
virtual:
enabled: true适用场景:
重要变化: Tomcat 11 升级到 Jakarta WebSocket 2.2,带来显著的性能和可扩展性提升。
主要改进:
与 HTTP/2 和异步处理的协同:
Tomcat 11 的 WebSocket 改进与 HTTP/2 支持和异步处理能力协同工作,确保更响应式和可扩展的 Web 应用。
重要变化: Jakarta Servlet 6.1 改进了 Web 应用处理 HTTP 请求的方式,特别是异步请求处理。
主要改进:
重要变化: Tomcat 11 引入了多项安全增强。
主要改进:
Tomcat 11 要求至少 Java SE 17,这个和 Spring Boot 4 的要求一致。
影响:
如果你用的是 Java 22+,Tomcat 11 支持通过 FFM(Foreign Function & Memory API)使用 OpenSSL,性能会更好。
重要提醒: 迁移到 Tomcat 11 的一个挑战性方面是需要重构应用以适应从 javax.* 到 jakarta.* 命名空间的切换。
影响:
注意: 如果你还在使用 Spring Boot 2.x,需要先升级到 Spring Boot 3.x(已完成 javax.* 到 jakarta.* 迁移),然后再考虑升级到 Spring Boot 4.0。
Tomcat 11 使用 header name 的原始大小写来存储 HTTP/1.1 request headers,而不是强制将其转换为小写。以前 Tomcat 会自动转小写,现在不会了。
主要影响:
HttpHeaders API 也有相应变化Spring Boot 4.0 这次移除了 36 个废弃类,大概占了所有废弃 API 的 88%。迁移的时候这些地方需要特别注意:
影响: 测试代码中广泛使用。旧写法:
// Spring Boot 3.x (已废弃,4.0 移除)
@SpringBootTest
class UserServiceTest {
@MockBean
private UserRepository userRepository;
}新写法:
// Spring Boot 4.0 (使用 Spring 官方支持)
@SpringBootTest
class UserServiceTest {
@MockitoBean
private UserRepository userRepository;
}Spring Boot 4.0 移除了该监听器,使用 Spring 的原生 Mockito 支持。
该改动在 Spring Boot 3.x 时已废弃,4.0 正式移除。
旧写法:
// Spring Boot 2.x/3.x (已废弃)
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated();
}
}需要改成新的方式:
// Spring Boot 4.0
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.build();
}
}该改动在 Spring Boot 3.x 时已废弃,4.0 正式移除。
Undertow 目前不兼容 Servlet 6.1,Spring Boot 4.0 移除了对它的支持:
<!-- Spring Boot 4.0 不再支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>替代方案:
Spring Batch 现在默认在内存中存储元数据,不再使用数据库。这可能导致 Job 执行历史丢失:
<!-- 如果需要持久化元数据,显式添加 JDBC 支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch-jdbc</artifactId>
</dependency>Spring Pulsar 移除了 Reactor 支持,所以 Spring Boot 4.0 也相应移除了响应式 Pulsar 客户端的自动配置。
Spring Boot 4.0 移除了用于创建"完全可执行" jar 文件的嵌入式启动脚本支持。该功能仅适用于类 Unix 系统,且与 高效部署建议 冲突。
如果需要类似功能,可以使用 Gradle 的 application plugin 等替代方案。你仍然可以使用 Spring Boot 的构建插件创建 uber jar,并通过 java -jar 运行。
Spring Session Hazelcast 和 Spring Session MongoDB 现在分别由 Hazelcast 团队和 MongoDB 团队维护,Spring Boot 4.0 移除了对它们的直接支持。如需使用,请直接使用对应的 starter。
问题:Header 访问失败或行为不一致
升级到 Tomcat 11.0.12+ 和 Spring Framework 7.0 后,某些 header 访问可能出现问题。这是 Spring Boot 4 迁移中必须关注的坑。
原因:
HttpHeaders API 不再继承 MultiValueMap建议: 按照 RFC 7230 建议,全链路都统一使用小写 header 名称。
解决方案:
HttpHeaders 的使用方式:// 旧代码(Spring Framework 6.x)
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
String contentType = headers.getFirst("Content-Type");
// 新代码(Spring Framework 7.0)
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
String contentType = headers.getFirst("Content-Type"); // 仍然可用
// 或使用
boolean hasContentType = headers.contains("Content-Type"); // 大小写不敏感// 推荐:使用标准格式
headers.add("Content-Type", "application/json");
headers.add("Authorization", "Bearer token");
headers.add("X-Custom-Header", "value");// 问题代码:直接字符串比较可能失败
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
if (name.equals("content-type")) { // 可能失败,name 可能是 "Content-Type"
// ...
}
}
// 推荐:使用大小写不敏感比较
if (name.equalsIgnoreCase("content-type")) {
// ...
}// MockHttpServletRequest 的行为已更新
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Content-Type", "application/json");
// 以下都能正常工作(大小写不敏感)
assertThat(request.getHeader("Content-Type")).isNotNull();
assertThat(request.getHeader("content-type")).isNotNull();
assertThat(request.getHeader("CONTENT-TYPE")).isNotNull();
// 但遍历时需要注意原始大小写
Enumeration<String> names = request.getHeaderNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
// name 可能是 "Content-Type" 而不是 "content-type"
assertThat(name).isEqualTo("Content-Type"); // 使用原始大小写
}问题:JSpecify 注解导致 Kotlin 或空值检查工具报错
Kotlin 项目可能遇到以下错误:
error: [nullness] incompatible types in return.
required: @NonNull String
found: @Nullable String解决方案:
// Kotlin 中处理可空类型
val user: User? = userService.findUser("123")
val name: String = user?.name ?: "Unknown"或者临时禁用严格空值检查:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-Xlint:-nullness</arg>
</compilerArgs>
</configuration>
</plugin>问题:JSON 序列化/反序列化行为变更
Jackson 3.x 的行为和 2.x 有些不一样,可能会导致一些序列化问题。
解决方案:
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
// 恢复 Jackson 2.x 的兼容性行为
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.registerModule(new JavaTimeModule());
return mapper;
}
}问题:某些库依赖旧版本的 Spring 或 Jakarta API
部分第三方库可能尚未适配 Spring Boot 4.0。
解决方案:
<dependency>
<groupId>com.example</groupId>
<artifactId>legacy-library</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>问题:升级后找不到 Job 执行历史
升级后 Job 执行历史丢失,原因是 Spring Batch 默认行为变更。
解决方案:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch-jdbc</artifactId>
</dependency>spring:
batch:
jdbc:
initialize-schema: always问题:spring-boot-starter-undertow 不再可用
解决方案:切换到 Tomcat:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 默认使用 Tomcat,无需额外配置 -->
</dependency>如果需要 Jetty:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>问题:启用虚拟线程后性能无明显提升
可能原因:
synchronized)解决方案:
# 优化数据库连接池
spring:
datasource:
hikari:
maximum-pool-size: 50 # 虚拟线程环境可适当增加
minimum-idle: 10
# 确保启用虚拟线程
spring:
threads:
virtual:
enabled: true使用 JFR (Java Flight Recorder) 分析:
java -XX:StartFlightRecording=filename=recording.jfr -jar app.jar问题:测试上下文自动暂停导致测试变慢
Spring Framework 7 的测试上下文暂停机制可能导致测试变慢。
解决方案:
调整测试上下文缓存配置:
@SpringBootTest
@TestPropertySource(properties = {
"spring.test.context.cache.maxSize=10"
})
class MyTest {
// ...
}OpenRewrite 是开源的自动化代码重构工具,支持 Spring Boot 迁移。
Maven 集成:
<build>
<plugins>
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>5.40.0</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0</recipe>
</activeRecipes>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-spring</artifactId>
<version>5.22.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>Gradle 集成:
plugins {
id 'org.openrewrite.rewrite' version '6.25.0'
}
rewrite {
activeRecipe('org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0')
}
dependencies {
rewrite 'org.openrewrite.recipe:rewrite-spring:5.22.0'
}运行迁移:
# Maven: 预览变更
mvn rewrite:dryRun
# Maven: 应用变更
mvn rewrite:run
# Gradle: 预览变更
./gradlew rewriteDryRun
# Gradle: 应用变更
./gradlew rewriteRun主要功能:
@MockBean → @MockitoBean)WebSecurityConfigurerAdapter)OpenRewrite 会自动将:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
}
}重构为:
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.authorizeHttpRequests(auth ->
auth.anyRequest().authenticated()
).build();
}
}Spring Boot Migrator 是 Spring 官方的实验性工具,基于 OpenRewrite,专门用于将传统 Spring 应用迁移到 Spring Boot,同时提供 Spring Boot 版本升级。
主要功能:
# 安装
git clone https://github.com/spring-projects-experimental/spring-boot-migrator.git
cd spring-boot-migrator
./mvnw clean install
# 扫描项目
java -jar applications/cli/target/spring-boot-migrator.jar scan /path/to/project
# 应用迁移
java -jar applications/cli/target/spring-boot-migrator.jar migrate /path/to/projectWindup 是 Red Hat 提供的 Java 应用现代化和迁移工具,支持大规模 Java 应用迁移。
主要功能:
适用场景:
IntelliJ IDEA 2025.3+ 内置了 Spring Boot 4 迁移支持:
pom.xml 或 build.gradle从 Spring Boot 2.x 迁移时,可使用 Eclipse Transformer 批量转换 javax.* 到 jakarta.*:
java -jar transformer.jar /path/to/project /path/to/output2025 年 11 月,Spring Boot 4.0 正式发布,这次升级被业界称为爆炸性升级。同时对于云原生应用而言,这是一次不可错过的性能与效率跃迁:
但这次升级也带来了 36 个废弃 API 移除、模块化架构重构、Tomcat 11 变更等挑战。本文基于 Spring Boot 官方文档和生产环境迁移经验,从原理到踩坑,提供完整、实用的迁移指南,助你平稳完成云原生应用的升级。
作为 Spring Boot 3.x 之后的首个大版本更新,Spring Boot 4.0 基于 Spring Framework 7.0、Jakarta EE 11 和 Java 17+(推荐 Java 21 或 25),带来了模块化架构重构、虚拟线程原生支持、HTTP 服务客户端自动配置等重大变化。
Spring Boot 4.0 配套使用 Spring Cloud 2025.1.x。虽然版本号看起来只是中号版本变更,但实际上这是一次大版本变更,包含了大量破坏性变更和重要更新。
Spring Boot 4 将 spring-boot-autoconfigure 拆分为多个专注的模块,每个技术都有独立的 starter 和对应的测试 starter。
主要变化:
spring-boot-<technology>,包路径:org.springframework.boot.<technology>spring-boot-starter-<technology> 和 spring-boot-starter-<technology>-test模块化的优势:
spring-boot-autoconfigure 是 2 MiB,模块化后只引入需要的模块,显著减少占用WebClient(通过 spring-boot-starter-webclient),不会意外启用 Web 服务器自动配置,不再需要调用 SpringApplication.setWebApplicationType(WebApplicationType.NONE)spring-boot-starter-micrometer-metrics),而不需要完整的 Actuator 依赖链测试支持的模块化:
spring-boot-test-autoconfigure 也被模块化了。测试相关的注解现在位于对应的测试模块中。例如,@AutoConfigureDataJdbc 注解现在位于 spring-boot-starter-data-jdbc-test 模块中,与 spring-boot-starter-data-jdbc 对齐。
测试 Starter 的传递性:
所有 test starter 都会传递性地引入 spring-boot-starter-test,因此不需要再单独声明 spring-boot-starter-test。只需要列出被测试技术对应的 test starter 即可。
主要废弃 Starter 和替代方案:
| 废弃 Starter | 替代 |
|---|---|
spring-boot-starter-web | spring-boot-starter-webmvc |
spring-boot-starter-aop | spring-boot-starter-aspectj |
spring-boot-starter-oauth2-authorization-server | spring-boot-starter-security-oauth2-authorization-server |
spring-boot-starter-oauth2-client | spring-boot-starter-security-oauth2-client |
spring-boot-starter-oauth2-resource-server | spring-boot-starter-security-oauth2-resource-server |
spring-boot-starter-web-services | spring-boot-starter-webservices |
其他迁移要点:
-test starter,如 spring-boot-starter-security-test完整的 Starter 列表:
Spring Boot 4.0 统一了 starter 的使用方式:大多数技术都有专门的 starter,每个 starter 都有对应的 test starter。以下是完整的列表(参考 官方迁移指南 ):
| Technology | Main Dependency | Test Dependency |
|---|---|---|
| Core Starters | ||
| AspectJ | spring-boot-starter-aspectj | spring-boot-starter-aspectj-test |
| Cloud Foundry Support | spring-boot-starter-cloudfoundry | spring-boot-starter-cloudfoundry-test |
| Jakarta Validation | spring-boot-starter-validation | spring-boot-starter-validation-test |
| Kotlin Serialization | spring-boot-starter-kotlin-serialization | spring-boot-starter-kotlin-serialization-test |
| Reactor | spring-boot-starter-reactor | spring-boot-starter-reactor-test |
| Web Server Starters | ||
| Jetty | spring-boot-starter-jetty | none |
| Reactor Netty | spring-boot-starter-reactor-netty | none |
| Tomcat | spring-boot-starter-tomcat | none |
| Web Client Starters | ||
Spring’s Imperative RestClient and RestTemplate | spring-boot-starter-restclient | spring-boot-starter-restclient-test |
Spring’s Reactive WebClient | spring-boot-starter-webclient | spring-boot-starter-webclient-test |
| Web Starters | ||
| Jersey | spring-boot-starter-jersey | spring-boot-starter-jersey-test |
| Spring GraphQL | spring-boot-starter-graphql | spring-boot-starter-graphql-test |
| Spring HATEOAS | spring-boot-starter-hateoas | spring-boot-starter-hateoas-test |
| Spring Session Data Redis | spring-boot-starter-session-data-redis | spring-boot-starter-session-data-redis-test |
| Spring Session JDBC | spring-boot-starter-session-jdbc | spring-boot-starter-session-jdbc-test |
| Spring Web MVC | spring-boot-starter-webmvc | spring-boot-starter-webmvc-test |
| Spring WebFlux | spring-boot-starter-webflux | spring-boot-starter-webflux-test |
| Spring Webservices | spring-boot-starter-webservices | spring-boot-starter-webservices-test |
| Database Starters | ||
| Cassandra | spring-boot-starter-cassandra | spring-boot-starter-cassandra-test |
| Couchbase | spring-boot-starter-couchbase | spring-boot-starter-couchbase-test |
| Elasticsearch | spring-boot-starter-elasticsearch | spring-boot-starter-elasticsearch-test |
| Flyway | spring-boot-starter-flyway | spring-boot-starter-flyway-test |
| JDBC | spring-boot-starter-jdbc | spring-boot-starter-jdbc-test |
| jOOQ | spring-boot-starter-jooq | spring-boot-starter-jooq-test |
| Liquibase | spring-boot-starter-liquibase | spring-boot-starter-liquibase-test |
| LDAP | spring-boot-starter-ldap | spring-boot-starter-ldap-test |
| MongoDB | spring-boot-starter-mongodb | spring-boot-starter-mongodb-test |
| Neo4J | spring-boot-starter-neo4j | spring-boot-starter-neo4j-test |
| R2DBC | spring-boot-starter-r2dbc | spring-boot-starter-r2dbc-test |
| Spring Data Starters | ||
| Spring Data Cassandra | spring-boot-starter-data-cassandra 或 spring-boot-starter-data-cassandra-reactive | spring-boot-starter-data-cassandra-test 或 spring-boot-starter-data-cassandra-reactive-test |
| Spring Data Couchbase | spring-boot-starter-data-couchbase 或 spring-boot-starter-data-couchbase-reactive | spring-boot-starter-data-couchbase-test 或 spring-boot-starter-data-couchbase-reactive-test |
| Spring Data Elasticsearch | spring-boot-starter-data-elasticsearch | spring-boot-starter-data-elasticsearch-test |
| Spring Data JDBC | spring-boot-starter-data-jdbc | spring-boot-starter-data-jdbc-test |
| Spring Data JPA (using Hibernate) | spring-boot-starter-data-jpa | spring-boot-starter-data-jpa-test |
| Spring Data LDAP | spring-boot-starter-data-ldap | spring-boot-starter-data-ldap-test |
| Spring Data MongoDB | spring-boot-starter-data-mongodb 或 spring-boot-starter-data-mongodb-reactive | spring-boot-starter-data-mongodb-test 或 spring-boot-starter-data-mongodb-reactive-test |
| Spring Data Neo4J | spring-boot-starter-data-neo4j | spring-boot-starter-data-neo4j-test |
| Spring Data R2DBC | spring-boot-starter-data-r2dbc | spring-boot-starter-data-r2dbc-test |
| Spring Data Redis | spring-boot-starter-data-redis 或 spring-boot-starter-data-redis-reactive | spring-boot-starter-data-redis-test 或 spring-boot-starter-data-redis-reactive-test |
| Spring Data REST | spring-boot-starter-data-rest | spring-boot-starter-data-rest-test |
| IO Starters | ||
| Hazelcast | spring-boot-starter-hazelcast | spring-boot-starter-hazelcast-test |
spring-boot-starter-mail | spring-boot-starter-mail-test | |
| Quartz | spring-boot-starter-quartz | spring-boot-starter-quartz-test |
| SendGrid | spring-boot-starter-sendgrid | spring-boot-starter-sendgrid-test |
| Spring Caching Support | spring-boot-starter-cache | spring-boot-starter-cache-test |
| Spring Batch (with JDBC) | spring-boot-starter-batch-jdbc | spring-boot-starter-batch-jdbc-test |
| Spring Batch (without JDBC) | spring-boot-starter-batch | spring-boot-starter-batch-test |
| JSON Starters | ||
| GSON | spring-boot-starter-gson | spring-boot-starter-gson-test |
| Jackson | spring-boot-starter-jackson | spring-boot-starter-jackson-test |
| JSONB | spring-boot-starter-jsonb | spring-boot-starter-jsonb-test |
| Messaging Starters | ||
| ActiveMQ | spring-boot-starter-activemq | spring-boot-starter-activemq-test |
| Artemis | spring-boot-starter-artemis | spring-boot-starter-artemis-test |
| JMS | spring-boot-starter-jms | spring-boot-starter-jms-test |
| RSocket | spring-boot-starter-rsocket | spring-boot-starter-rsocket-test |
| Spring AMQP | spring-boot-starter-amqp | spring-boot-starter-amqp-test |
| Spring Integration | spring-boot-starter-integration | spring-boot-starter-integration-test |
| Spring for Apache Kafka | spring-boot-starter-kafka | spring-boot-starter-kafka-test |
| Spring for Apache Pulsar | spring-boot-starter-pulsar | spring-boot-starter-pulsar-test |
| Websockets | spring-boot-starter-websocket | spring-boot-starter-websocket-test |
| Security Starters | ||
| Spring Security | spring-boot-starter-security | spring-boot-starter-security-test |
| Spring Security OAuth Authorization Server | spring-boot-starter-security-oauth2-authorization-server | spring-boot-starter-security-oauth2-authorization-server-test |
| Spring Security OAuth Client | spring-boot-starter-security-oauth2-client | spring-boot-starter-security-oauth2-client-test |
| Spring Security OAuth Resource Server | spring-boot-starter-security-oauth2-resource-server | spring-boot-starter-security-oauth2-resource-server-test |
| Spring Security SAML | spring-boot-starter-security-saml2 | spring-boot-starter-security-saml2-test |
| Templating Starters | ||
| Freemarker | spring-boot-starter-freemarker | spring-boot-starter-freemarker-test |
| Groovy Templates | spring-boot-starter-groovy-templates | spring-boot-starter-groovy-templates-test |
| Mustache | spring-boot-starter-mustache | spring-boot-starter-mustache-test |
| Thymeleaf | spring-boot-starter-thymeleaf | spring-boot-starter-thymeleaf-test |
| Production-Ready Starters | ||
| Actuator | spring-boot-starter-actuator | spring-boot-starter-actuator-test |
| Micrometer Metrics | spring-boot-starter-micrometer-metrics | spring-boot-starter-micrometer-metrics-test |
| OpenTelemetry | spring-boot-starter-opentelemetry | spring-boot-starter-opentelemetry-test |
| Zipkin | spring-boot-starter-zipkin | spring-boot-starter-zipkin-test |
提示: 所有 test starter 都会传递性地引入
spring-boot-starter-test,因此不需要再单独声明spring-boot-starter-test。只需要列出被测试技术对应的 test starter 即可。
Classic Starters(快速迁移方案):
如果需要快速迁移,可以使用 Classic Starters,它们提供了类似 Spring Boot 3.x 的 classpath,让你可以快速恢复所有基础设施的可用性:
<!-- 替代 spring-boot-starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-classic</artifactId>
</dependency>
<!-- 替代 spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test-classic</artifactId>
<scope>test</scope>
</dependency>使用 Classic Starters 的好处:
迁移建议(官方推荐的两步法):
注意: 官方建议最终还是要迁移到模块化的 starter,Classic Starters 只是过渡方案。完整的 starter 列表和对应关系请参考 官方迁移指南 。
Spring Boot 4 引入了新的注解 @ConfigurationPropertiesSource,允许 Spring Boot 读取外部模块中定义的 @ConfigurationProperties 类型,这在之前是不可能的。
使用场景:
@ConfigurationPropertiesSource("com.example.config")
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
// getters and setters
}优势:
Spring Boot 4 现在支持配置多个 TaskDecorator Bean,允许你组合多个装饰器来增强任务执行行为。
使用示例:
@Configuration
public class TaskConfig {
@Bean
public TaskDecorator loggingTaskDecorator() {
return runnable -> {
return () -> {
System.out.println("Task started: " + Thread.currentThread().getName());
try {
runnable.run();
} finally {
System.out.println("Task completed");
}
};
};
}
@Bean
public TaskDecorator mdcTaskDecorator() {
return runnable -> {
String traceId = MDC.get("traceId");
return () -> {
MDC.put("traceId", traceId);
try {
runnable.run();
} finally {
MDC.clear();
}
};
};
}
}多个 TaskDecorator 会按顺序应用,提供更灵活的任务执行增强能力。
模块化架构对包结构也有影响。每个模块现在都有独立的 org.springframework.boot.<module> 包路径。根据模块的职责范围,可能包含 API、自动配置、Actuator 相关支持等。
示例:
// Spring Boot 3.x
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
// Spring Boot 4.0
import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration;主要变化:
org.springframework.boot.<technology>org.springframework.boot.<technology>.testSpring Boot 4 基于 Spring Framework 7.0 构建,继承了以下特性。
Spring Framework 7 原生支持 API 版本管理,这是首次在 Spring 框架中提供官方支持。之前虽然可以通过 @RequestMapping 实现,但需要大量手动工作。
配置方式:
Java 配置:
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void configureApiVersioning(ApiVersionConfigurer configurer) {
configurer.useRequestHeader("API-Version");
// 或使用其他策略:
// configurer.useQueryParameter("version");
// configurer.usePathPattern("/api/{version}");
// configurer.useMediaType("application/vnd.api.v1+json");
}
}Spring Boot 配置属性:
spring:
mvc:
apiversion:
use:
header: API-Version
# 或使用:
# query-parameter: version
# path-pattern: /api/{version}使用示例:
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping(value = "/users", version = "1")
public List<UserV1> getUsersV1() {
return userService.getUsersV1();
}
@GetMapping(value = "/users", version = "2")
public List<UserV2> getUsersV2() {
return userService.getUsersV2();
}
}功能式端点支持:
RouterFunction<ServerResponse> route = RouterFunctions.route()
.GET("/hello-world", version("1.2"),
request -> ServerResponse.ok().body("Hello World"))
.build();支持的版本控制策略:
/v1/users、/v2/users(需要在路径中声明 URI 变量)X-API-Version: 1 或自定义 header 名称/users?version=1Accept: application/vnd.api.v1+json版本格式:
默认使用语义化版本(Semantic Versioning),支持 major.minor.patch 格式。如果未指定 minor 和 patch,默认为 0。版本解析器可以自定义,支持日期格式或其他格式。
废弃处理:
API 版本控制支持 RFC 9745 标准的废弃处理,可以在响应中发送废弃提示。
Spring Framework 7 迁移到 JSpecify 注解,这是 Spring 生态系统中空安全支持的重大里程碑。JSpecify 是一个由 OpenJDK、Broadcom、Google、JetBrains、Sonar 等组织共同参与的标准项目。
已支持 JSpecify 的 Spring 项目:
使用示例:
import org.jspecify.annotations.Nullable;
import org.jspecify.annotations.NonNull;
public class UserService {
public @NonNull User getUser(@NonNull String userId) {
return userRepository.findById(userId)
.orElseThrow(() -> new UserNotFoundException(userId));
}
public @Nullable User findUser(@NonNull String email) {
return userRepository.findByEmail(email).orElse(null);
}
}IDE 支持:
Kotlin 项目注意事项:
JSpecify 注解会明确标记可空性,Kotlin 编译器会自动识别并转换。如果 Java 接口使用 @Nullable 注解,Kotlin 实现必须返回可空类型;如果使用 @NonNull,则必须返回非空类型。IntelliJ IDEA 会提供相应的编译错误提示和修复建议。
Spring Framework 7.0 引入了多线程异步启动机制,可以并行初始化 ApplicationContext,显著加快应用启动速度。
工作原理:
配置方式:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
// 启用异步启动
app.setApplicationStartup(new BufferingApplicationStartup(1000));
app.run(args);
}
}或者通过配置属性:
spring:
application:
startup:
enabled: true性能提升:
注意事项:
Spring Framework 7 和 Spring Boot 4 大幅简化了 HTTP 接口客户端的配置。之前需要手动创建 HttpServiceProxyFactory 和配置每个客户端,现在可以通过声明式方式自动注册。
建议: 虽然 RestTemplate 仍可使用,但推荐使用 RestClient 或 HTTP 接口客户端(@HttpExchange)作为替代方案。
旧方式(Spring Framework 6 / Spring Boot 3):
@HttpExchange(url = "/api/users")
public interface UserClient {
@GetExchange("/{id}")
User getUser(@PathVariable String id);
@PostExchange
User createUser(@RequestBody UserRequest request);
}
// 需要手动配置每个客户端
@Configuration
public class HttpClientConfig {
@Bean
public UserClient userClient(RestClient.Builder builder) {
RestClient restClient = builder.baseUrl("https://api.example.com").build();
HttpServiceProxyFactory factory = HttpServiceProxyFactory
.builderFor(RestClientAdapter.create(restClient)).build();
return factory.createClient(UserClient.class);
}
// 如果有多个客户端,需要重复配置。..
}新方式(Spring Framework 7 / Spring Boot 4):
使用 @ImportHttpServices 注解:
@HttpExchange(url = "/api/users")
public interface UserClient {
@GetExchange("/{id}")
User getUser(@PathVariable String id);
@PostExchange
User createUser(@RequestBody UserRequest request);
}
@Configuration
@ImportHttpServices(group = "api", types = {UserClient.class})
public class HttpClientConfig {
}配置 application.yml:
spring:
http:
client:
service:
read-timeout: 2s
group:
api:
base-url: https://api.example.com或使用包扫描自动发现:
@Configuration
@ImportHttpServices(group = "api", basePackages = "com.example.client")
public class HttpClientConfig {
}多组配置示例:
如果应用需要集成多个 REST API,可以为每个 API 配置不同的组:
@Configuration
@ImportHttpServices(group = "github", basePackages = "com.example.client.github")
@ImportHttpServices(group = "stackoverflow", basePackages = "com.example.client.stackoverflow")
public class HttpClientConfig {
}对应的配置:
spring:
http:
client:
service:
group:
github:
base-url: https://api.github.com
read-timeout: 5s
stackoverflow:
base-url: https://api.stackexchange.com
read-timeout: 10s使用 WebClient(响应式):
默认使用 RestClient,如需使用 WebClient,可通过配置切换:
@Configuration
@ImportHttpServices(
group = "api",
basePackages = "com.example.client",
clientType = ClientType.WEB_CLIENT
)
public class HttpClientConfig {
}优势:
HttpServiceProxyFactory 和 Bean这样 com.example.client 包下所有带 @HttpExchange 的接口都会自动注册为 Spring Bean,可以直接注入使用:
@Service
public class UserService {
private final UserClient userClient; // 直接注入,无需手动配置
public UserService(UserClient userClient) {
this.userClient = userClient;
}
public User getUser(String id) {
return userClient.getUser(id); // 直接使用
}
}Spring Framework 7 引入了强大的弹性工具,直接集成到核心框架中:
配置方式:
@Configuration
@EnableResilientMethods
public class ApplicationConfig {
}
@Service
public class PaymentService {
@Retryable(
maxAttempts = 3,
backoff = @Retryable.Backoff(delay = 2000, multiplier = 2.0)
)
@ConcurrencyLimit(value = 2) // 只允许 2 个并发调用
public void processPayment(String paymentId) {
// 处理支付逻辑
}
}优势:
Spring Framework 7 引入了 JmsClient,类似于 JdbcClient 和 RestClient,提供流畅的构建器风格 API。这是对传统 JMS 模板的更优雅和可读的替代方案。
使用示例:
@Service
public class MessageService {
private final JmsClient jmsClient;
public MessageService(JmsClient jmsClient) {
this.jmsClient = jmsClient;
}
public void sendMessage(String destination, String message) {
jmsClient.create()
.queue(destination)
.body(message)
.send();
}
public String receiveMessage(String destination) {
return jmsClient.create()
.queue(destination)
.receive(String.class);
}
}优势:
JdbcClient、RestClient 保持一致的风格Spring Framework 7 简化了消息转换,引入了新的 HttpMessageConverters 配置类。这种统一方法借鉴了响应式编解码器的设计,简化了 HTTP 消息的序列化和反序列化。
Spring Framework 7 采用 Jakarta EE 11 规范:
JPA 3.2 重要变化:
之前,EntityManager 只能通过 @PersistenceContext 注解注入。现在,EntityManagerFactory 和共享的 EntityManager 都可以使用 @Inject 或 @Autowired 注入,并支持使用限定符来选择特定的持久化单元(当配置了多个持久化单元时)。
// 旧方式(仍然支持)
@PersistenceContext
private EntityManager entityManager;
// 新方式(Spring Framework 7 / JPA 3.2)
@Autowired
private EntityManager entityManager;
// 多个持久化单元时使用限定符
@Autowired
@Qualifier("primaryEntityManager")
private EntityManager primaryEntityManager;这里要提醒一下:javax.* 到 jakarta.* 的迁移应该在 Spring Boot 3.0 的时候就已经完成了。如果你还在用 Spring Boot 2.x,那得先升级到 3.x,然后再考虑 4.0。
Jackson 3.x 的破坏性变更:
ObjectMapper 行为变更迁移示例:
// Jackson 2.x
@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
private String name;
// ...
}
// Jackson 3.x (同样的语法,但内部行为可能不同)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class User {
private String name;
// ...
}Spring Framework 7 引入了一个挺有意思的测试上下文管理机制:
该机制可显著降低测试套件的内存占用。
支持 Optional 类型和 Elvis 操作符:
@Value("#{userService.findUser('123')?.name ?: 'Unknown'}")
private String userName;Spring Framework 7 引入了 BeanRegistrar 接口,允许在 @ConditionalOn... 注解族不够用时进行动态 Bean 注册。
Java 实现:
import org.springframework.context.bean.BeanRegistrar;
import org.springframework.context.bean.BeanRegistry;
public class QuoteProviderRegistrar implements BeanRegistrar {
@Override
public void register(BeanRegistry registry, Environment env) {
registry.registerBean("quoteProviderDb", QuoteProviderDb.class);
registry.registerBean("quoteProviderFallback",
QuoteProviderFallback.class,
spec -> {
spec.fallback();
spec.order(1);
});
}
}Kotlin DSL 实现(更优雅):
Kotlin 2.2 提供了 BeanRegistrarDsl,让 Bean 注册更加简洁:
import org.springframework.context.bean.BeanRegistrarDsl
class QuoteProviderRegistrar : BeanRegistrarDsl({
registerBean<QuoteProviderDb>("quoteProviderDb")
registerBean<QuoteProviderFallback>(
name = "quoteProviderFallback",
fallback = true,
order = 1
)
})使用场景:
@ConditionalOn... 注解的能力范围Tomcat 11 是 Apache Tomcat 项目第九个主要版本,标志着从传统 Java EE 向现代 Jakarta EE 框架的重要转变。本次升级支持 Jakarta EE 11,实现了:
重要特性: Tomcat 11 原生支持 Java 21 的 Project Loom 虚拟线程,这是本次升级的核心亮点之一。
性能数据(基于实际测试):
根据 Fast Thread 和 Java Code Geeks 的性能基准测试:
| 场景 | 平台线程 | 虚拟线程 | 性能提升 |
|---|---|---|---|
| I/O 密集型应用(数据库查询、HTTP 调用) | 基准 | 2-3x 吞吐量 | +100-200% |
| 高并发 Web 请求(1000+ 并发) | 基准 | 2-3x 吞吐量 | +100-200% |
| CPU 密集型应用 | 基准 | 无明显提升 | 0% |
| 内存占用 | 基准 | -30-50%(线程栈) | -30-50% |
| 响应时间(P99) | 基准 | -20-40% | -20-40% |
适用场景:
实际案例:
一个典型的 Spring Boot Web 应用(处理 REST 请求,调用数据库和外部 API):
优势:
配置方式:
在 Spring Boot 4 中,虚拟线程支持通过配置属性启用:
spring:
threads:
virtual:
enabled: true适用场景:
重要变化: Tomcat 11 升级到 Jakarta WebSocket 2.2,带来显著的性能和可扩展性提升。
主要改进:
与 HTTP/2 和异步处理的协同:
Tomcat 11 的 WebSocket 改进与 HTTP/2 支持和异步处理能力协同工作,确保更响应式和可扩展的 Web 应用。
重要变化: Jakarta Servlet 6.1 改进了 Web 应用处理 HTTP 请求的方式,特别是异步请求处理。
主要改进:
重要变化: Tomcat 11 引入了多项安全增强。
主要改进:
Tomcat 11 要求至少 Java SE 17,这个和 Spring Boot 4 的要求一致。
影响:
如果你用的是 Java 22+,Tomcat 11 支持通过 FFM(Foreign Function & Memory API)使用 OpenSSL,性能会更好。
重要提醒: 迁移到 Tomcat 11 的一个挑战性方面是需要重构应用以适应从 javax.* 到 jakarta.* 命名空间的切换。
影响:
注意: 如果你还在使用 Spring Boot 2.x,需要先升级到 Spring Boot 3.x(已完成 javax.* 到 jakarta.* 迁移),然后再考虑升级到 Spring Boot 4.0。
Tomcat 11 使用 header name 的原始大小写来存储 HTTP/1.1 request headers,而不是强制将其转换为小写。以前 Tomcat 会自动转小写,现在不会了。
主要影响:
HttpHeaders API 也有相应变化Spring Boot 4.0 这次移除了 36 个废弃类,大概占了所有废弃 API 的 88%。迁移的时候这些地方需要特别注意:
影响: 测试代码中广泛使用。旧写法:
// Spring Boot 3.x (已废弃,4.0 移除)
@SpringBootTest
class UserServiceTest {
@MockBean
private UserRepository userRepository;
}新写法:
// Spring Boot 4.0 (使用 Spring 官方支持)
@SpringBootTest
class UserServiceTest {
@MockitoBean
private UserRepository userRepository;
}Spring Boot 4.0 移除了该监听器,使用 Spring 的原生 Mockito 支持。
该改动在 Spring Boot 3.x 时已废弃,4.0 正式移除。
旧写法:
// Spring Boot 2.x/3.x (已废弃)
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated();
}
}需要改成新的方式:
// Spring Boot 4.0
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
)
.build();
}
}该改动在 Spring Boot 3.x 时已废弃,4.0 正式移除。
Undertow 目前不兼容 Servlet 6.1,Spring Boot 4.0 移除了对它的支持:
<!-- Spring Boot 4.0 不再支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>替代方案:
Spring Batch 现在默认在内存中存储元数据,不再使用数据库。这可能导致 Job 执行历史丢失:
<!-- 如果需要持久化元数据,显式添加 JDBC 支持 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch-jdbc</artifactId>
</dependency>Spring Pulsar 移除了 Reactor 支持,所以 Spring Boot 4.0 也相应移除了响应式 Pulsar 客户端的自动配置。
Spring Boot 4.0 移除了用于创建"完全可执行" jar 文件的嵌入式启动脚本支持。该功能仅适用于类 Unix 系统,且与 高效部署建议 冲突。
如果需要类似功能,可以使用 Gradle 的 application plugin 等替代方案。你仍然可以使用 Spring Boot 的构建插件创建 uber jar,并通过 java -jar 运行。
Spring Session Hazelcast 和 Spring Session MongoDB 现在分别由 Hazelcast 团队和 MongoDB 团队维护,Spring Boot 4.0 移除了对它们的直接支持。如需使用,请直接使用对应的 starter。
问题:Header 访问失败或行为不一致
升级到 Tomcat 11.0.12+ 和 Spring Framework 7.0 后,某些 header 访问可能出现问题。这是 Spring Boot 4 迁移中必须关注的坑。
原因:
HttpHeaders API 不再继承 MultiValueMap建议: 按照 RFC 7230 建议,全链路都统一使用小写 header 名称。
解决方案:
HttpHeaders 的使用方式:// 旧代码(Spring Framework 6.x)
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
String contentType = headers.getFirst("Content-Type");
// 新代码(Spring Framework 7.0)
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
String contentType = headers.getFirst("Content-Type"); // 仍然可用
// 或使用
boolean hasContentType = headers.contains("Content-Type"); // 大小写不敏感// 推荐:使用标准格式
headers.add("Content-Type", "application/json");
headers.add("Authorization", "Bearer token");
headers.add("X-Custom-Header", "value");// 问题代码:直接字符串比较可能失败
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
if (name.equals("content-type")) { // 可能失败,name 可能是 "Content-Type"
// ...
}
}
// 推荐:使用大小写不敏感比较
if (name.equalsIgnoreCase("content-type")) {
// ...
}// MockHttpServletRequest 的行为已更新
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Content-Type", "application/json");
// 以下都能正常工作(大小写不敏感)
assertThat(request.getHeader("Content-Type")).isNotNull();
assertThat(request.getHeader("content-type")).isNotNull();
assertThat(request.getHeader("CONTENT-TYPE")).isNotNull();
// 但遍历时需要注意原始大小写
Enumeration<String> names = request.getHeaderNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
// name 可能是 "Content-Type" 而不是 "content-type"
assertThat(name).isEqualTo("Content-Type"); // 使用原始大小写
}问题:JSpecify 注解导致 Kotlin 或空值检查工具报错
Kotlin 项目可能遇到以下错误:
error: [nullness] incompatible types in return.
required: @NonNull String
found: @Nullable String解决方案:
// Kotlin 中处理可空类型
val user: User? = userService.findUser("123")
val name: String = user?.name ?: "Unknown"或者临时禁用严格空值检查:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-Xlint:-nullness</arg>
</compilerArgs>
</configuration>
</plugin>问题:JSON 序列化/反序列化行为变更
Jackson 3.x 的行为和 2.x 有些不一样,可能会导致一些序列化问题。
解决方案:
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
// 恢复 Jackson 2.x 的兼容性行为
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.registerModule(new JavaTimeModule());
return mapper;
}
}问题:某些库依赖旧版本的 Spring 或 Jakarta API
部分第三方库可能尚未适配 Spring Boot 4.0。
解决方案:
<dependency>
<groupId>com.example</groupId>
<artifactId>legacy-library</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>问题:升级后找不到 Job 执行历史
升级后 Job 执行历史丢失,原因是 Spring Batch 默认行为变更。
解决方案:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch-jdbc</artifactId>
</dependency>spring:
batch:
jdbc:
initialize-schema: always问题:spring-boot-starter-undertow 不再可用
解决方案:切换到 Tomcat:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 默认使用 Tomcat,无需额外配置 -->
</dependency>如果需要 Jetty:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>问题:启用虚拟线程后性能无明显提升
可能原因:
synchronized)解决方案:
# 优化数据库连接池
spring:
datasource:
hikari:
maximum-pool-size: 50 # 虚拟线程环境可适当增加
minimum-idle: 10
# 确保启用虚拟线程
spring:
threads:
virtual:
enabled: true使用 JFR (Java Flight Recorder) 分析:
java -XX:StartFlightRecording=filename=recording.jfr -jar app.jar问题:测试上下文自动暂停导致测试变慢
Spring Framework 7 的测试上下文暂停机制可能导致测试变慢。
解决方案:
调整测试上下文缓存配置:
@SpringBootTest
@TestPropertySource(properties = {
"spring.test.context.cache.maxSize=10"
})
class MyTest {
// ...
}OpenRewrite 是开源的自动化代码重构工具,支持 Spring Boot 迁移。
Maven 集成:
<build>
<plugins>
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version>5.40.0</version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0</recipe>
</activeRecipes>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-spring</artifactId>
<version>5.22.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>Gradle 集成:
plugins {
id 'org.openrewrite.rewrite' version '6.25.0'
}
rewrite {
activeRecipe('org.openrewrite.java.spring.boot4.UpgradeSpringBoot_4_0')
}
dependencies {
rewrite 'org.openrewrite.recipe:rewrite-spring:5.22.0'
}运行迁移:
# Maven: 预览变更
mvn rewrite:dryRun
# Maven: 应用变更
mvn rewrite:run
# Gradle: 预览变更
./gradlew rewriteDryRun
# Gradle: 应用变更
./gradlew rewriteRun主要功能:
@MockBean → @MockitoBean)WebSecurityConfigurerAdapter)OpenRewrite 会自动将:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().authenticated();
}
}重构为:
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http.authorizeHttpRequests(auth ->
auth.anyRequest().authenticated()
).build();
}
}Spring Boot Migrator 是 Spring 官方的实验性工具,基于 OpenRewrite,专门用于将传统 Spring 应用迁移到 Spring Boot,同时提供 Spring Boot 版本升级。
主要功能:
# 安装
git clone https://github.com/spring-projects-experimental/spring-boot-migrator.git
cd spring-boot-migrator
./mvnw clean install
# 扫描项目
java -jar applications/cli/target/spring-boot-migrator.jar scan /path/to/project
# 应用迁移
java -jar applications/cli/target/spring-boot-migrator.jar migrate /path/to/projectWindup 是 Red Hat 提供的 Java 应用现代化和迁移工具,支持大规模 Java 应用迁移。
主要功能:
适用场景:
IntelliJ IDEA 2025.3+ 内置了 Spring Boot 4 迁移支持:
pom.xml 或 build.gradle从 Spring Boot 2.x 迁移时,可使用 Eclipse Transformer 批量转换 javax.* 到 jakarta.*:
java -jar transformer.jar /path/to/project /path/to/output