我昨天看到 Spring Boot 4.1.0 正式发布,第一反应不是「又升级了」,而是 Spring 这条线真的进入新阶段了。
Spring Boot 4.0 去年已经把底座换了一轮:Spring Framework 7、Jakarta EE 11、Jackson 3、AOT、可观测性这些东西都往前推了一大步。4.1.0 不是再来一次大拆大建,它更像是在 4.x 这条新轨道上,把生产环境里最疼的几个点继续补硬。
这次官方 6 月 10 日发布,基于 Spring Framework 7.0.8,还带了一堆依赖升级和安全修复。你要说它有没有那种「一看就炸」的新语法?倒也没有。但它加的东西都很实在:gRPC 自动配置、HTTP 客户端 SSRF 防护、OpenTelemetry 增强、JPA 后台启动、懒加载 JDBC 连接、Jackson 配置更新、Log4j 文件轮转。
好家伙,这不是炫技,这是冲着生产系统来的。
gRPC 终于被 Spring Boot 正式拉上桌
我觉得 4.1.0 最值得看的第一个点,就是 Spring gRPC 支持。
以前你在 Spring Boot 里写 gRPC,不是不能写,但基本要靠第三方 starter,或者自己手动配 Server、Channel、拦截器、异常处理。项目一复杂,就开始东拼西凑,整的挺像那么回事,实际排查起来头大。
4.1.0 把 gRPC 自动配置纳进来了,服务端和客户端都能走 Spring Boot 的自动装配逻辑。你只要把 gRPC 服务注册成 Spring Bean,Boot 就能帮你发现 BindableService,再把服务挂到 gRPC Server 上。
一个服务大概长这样:
import io.grpc.stub.StreamObserver;
import org.springframework.grpc.server.service.GrpcService;
@GrpcService
publicclassUserGrpcServiceextendsUserServiceGrpc.UserServiceImplBase {
@Override
publicvoidgetUser(UserRequest request, StreamObserver responseObserver) {
// 这里正常接你的 Service、Repository,别在 gRPC 层写一坨业务
UserResponseresponse= UserResponse.newBuilder()
.setId(request.getId())
.setName("鹏磊")
.build();// gRPC 是流式响应模型,先 onNext,再 onCompleted
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
配置也能走 Boot 味儿:
spring:
grpc:
server:
port: 9090
这就比以前舒服多了。你不用每个项目都重新发明一套 gRPC 基础设施,异常处理、拦截器、观测指标这些也能跟 Spring 生态打通。
更关键的是,4.1 还引入了类似 @GrpcAdvice 的集中异常处理思路。HTTP 有 @ControllerAdvice,gRPC 也该有自己那套统一兜底。
import io.grpc.Status;
import org.springframework.grpc.server.exception.GrpcExceptionHandler;
import org.springframework.grpc.server.exception.GrpcExceptionHandlerAdvice;
@GrpcExceptionHandlerAdvice
class GlobalGrpcExceptionHandler {@GrpcExceptionHandler(IllegalArgumentException.class)
Status handleBadRequest(IllegalArgumentException ex) {
// 把业务异常转换成 gRPC 标准状态码,客户端就不会只收到一坨 UNKNOWN
return Status.INVALID_ARGUMENT.withDescription(ex.getMessage());
}
}
这东西看着不花哨,但生产里太有用了。微服务之间走 gRPC,最怕的就是异常语义乱飞。统一处理以后,调用方能拿到明确状态码,监控也更好做。
SSRF 防护,终于开始管出站请求了
第二个我觉得很硬的点,是 HTTP Client 的 SSRF 防护。
SSRF 这玩意儿,很多后端同学嘴上都知道,写代码时又容易忘。用户传一个 URL,你服务端帮他去请求,结果他传了内网地址、云厂商元数据地址、本机管理端口,你的应用就被当成跳板了。
Spring Boot 4.1.0 引入了基于 InetAddressFilter 的 HTTP 客户端防护能力,可以对阻塞式和响应式 HTTP Client 的出站地址做过滤。
比如你的系统允许用户提交 webhook URL,但你不想它请求内网网段,就可以做类似这种配置思路:
import java.net.InetAddress;
import java.util.Set;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.support.RestClientAdapter;
@Configuration
classHttpClientSecurityConfig {
@Bean
RestClient restClient(RestClient.Builder builder) {
// 这里只演示思路:真实项目要用 Boot 4.1 的 InetAddressFilter 能力接入客户端构建链路
return builder
.requestInterceptor((request, body, execution) -> {
Stringhost= request.getURI().getHost();
InetAddressaddress= InetAddress.getByName(host);
// 禁止访问本机、内网和链路本地地址,防止服务端被拿去探内网
if (address.isLoopbackAddress()
|| address.isSiteLocalAddress()
|| address.isLinkLocalAddress()) {
thrownewIllegalArgumentException("禁止访问内网地址: " + host);
}return execution.execute(request, body);
})
.build();
}
}
上面这段不是说让你手搓替代框架能力,而是让你看懂 Boot 4.1 这个特性背后的价值:出站 HTTP 请求不再是「想去哪就去哪」。
以前我们总盯着入站安全,鉴权、限流、参数校验一套一套。现在 AI 应用、Webhook、URL 预览、远程文件抓取越来越多,出站请求同样危险。Spring Boot 把 SSRF 防护往标准能力里推,这个方向很对。
懒加载 JDBC 连接,事务里少拿没用连接
第三个细节很小,但很工程。
Spring Boot 4.1.0 新增了 spring.datasource.connection-fetch,可以把自动配置的连接池 DataSource 包一层 LazyConnectionDataSourceProxy,让物理连接真正需要执行 SQL 时再从池子里拿。
配置就一行:
spring:
datasource:
# lazy 表示进事务不立刻拿连接,真执行 JDBC 语句时才取
connection-fetch: lazy
这个东西解决啥?
有些业务方法上挂了 @Transactional,但里面不一定每次都访问数据库。比如先查缓存,命中就直接返回;或者先做权限判断,不通过就抛异常。传统方式可能事务一开始就从连接池拿连接,最后发现根本没用上。
@Service
classOrderService {
privatefinal OrderRepository orderRepository;
privatefinal CacheService cacheService;
OrderService(OrderRepository orderRepository, CacheService cacheService) {
this.orderRepository = orderRepository;
this.cacheService = cacheService;
}
@Transactional(readOnly = true)
public OrderDetail queryOrder(String orderId) {
// 如果缓存命中,lazy 连接模式下这里不会白白占用 JDBC 连接
OrderDetailcached= cacheService.get(orderId);
if (cached != null) {
return cached;
}// 真正访问数据库时,才从连接池里取物理连接
return orderRepository.findDetail(orderId);
}
}
你别小看这点。高并发系统里,数据库连接池是稀缺资源。少拿一次没用连接,就少一点排队,少一点连接池被打满的风险。
这类优化没有标题党味儿,但线上很值钱。
OpenTelemetry 增强,可观测性继续往前拱
Spring Boot 这几年一直在把可观测性往框架底层塞,4.1.0 继续增强 OpenTelemetry 支持。
现在微服务链路一长,排查问题已经不能靠看日志硬猜了。一个请求从网关进来,穿过 HTTP、gRPC、消息队列、数据库,再到下游服务,没 Trace 真不行。
配置 OTLP 导出,大概是这种味儿:
management:
tracing:
sampling:
# 演示环境全量采样,生产别无脑 1.0,成本顶不住
probability:1.0
opentelemetry:
tracing:
export:
otlp:
# 默认 HTTP OTLP 端点,后面可以接 Collector
endpoint:http://localhost:4318/v1/traces
timeout:10s
业务代码里,你也可以把关键逻辑打进观测链路:
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationRegistry;
@Service
classPaymentService {
privatefinal ObservationRegistry observationRegistry;
PaymentService(ObservationRegistry observationRegistry) {
this.observationRegistry = observationRegistry;
}
publicvoidpay(String orderId) {
Observation.createNotStarted("payment.process", observationRegistry)
.lowCardinalityKeyValue("biz", "payment")
.observe(() -> {
// 这里包住真正的支付逻辑,Trace 里就能看到这段业务耗时
doPay(orderId);
});
}privatevoiddoPay(String orderId) {
// 调支付渠道、更新订单状态、发消息,这里只做示意
}
}
以前很多团队是线上出事了才想起补 Trace。现在 Boot 把这些能力越做越顺手,你不用再为接入观测写一堆乱七八糟的胶水代码。
尤其 gRPC 支持和观测拦截器打通以后,HTTP 和 gRPC 两条链路都能纳入统一监控。这个对混合协议微服务很关键。
Jackson 配置更新,4.x 生态继续清账
Spring Boot 4 这一代还有个大变化:Jackson 3。
4.1.0 继续补 Jackson 配置属性和自定义支持。这个点不如 gRPC 吸睛,但升级时很容易踩坑。
很多老项目里有一堆 ObjectMapper 自定义:时间格式、枚举序列化、忽略空值、未知字段处理。Boot 4 之后底层包名、默认行为、配置属性都有调整,你不能假设 3.x 项目里的序列化结果原封不动过来。
比如常见配置可以这样集中管理:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tools.jackson.databind.DeserializationFeature;
import tools.jackson.databind.ObjectMapper;
@Configuration
classJacksonConfig {@Bean
ObjectMapper objectMapper(ObjectMapper.Builder builder) {
// 忽略未知字段,避免第三方接口多返回字段就把我们干崩
return builder
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.build();
}
}
注意这里是 Jackson 3 的 tools.jackson 包,不是老的 com.fasterxml.jackson。这种地方最容易让人升级时骂娘。
我的建议是,升 4.1 之前,把接口出入参序列化测试补上。别等上线以后发现时间格式、枚举值、空字段变了,那才叫难受。
这次升级到底该不该冲
我觉得 Spring Boot 4.1.0 不是那种「所有项目今晚必须升」的版本。
如果你还在 Spring Boot 2.x,甚至 Java 8、Java 11,那别做梦一步上 4.1。先还技术债,Java 17、Jakarta 包名、Spring Framework 7、Jackson 3,这些都得过一遍。
如果你已经在 4.0.x,那 4.1.0 很值得评估。它不是换世界观,而是补生产能力。gRPC 正式接入,SSRF 防护加强,OpenTelemetry 更顺,JPA 和 JDBC 细节优化,这些都是真项目会用到的东西。
尤其是这几类项目,我建议重点看:一是内部服务之间已经开始用 gRPC 的;二是有 Webhook、远程 URL 抓取、AI 工具调用这类出站 HTTP 的;三是数据库连接池经常紧张的;四是正在统一 Trace、Metrics、Logs 的微服务系统。
Spring Boot 4.1.0 给我的感觉,不是「惊爆了」那种浮夸爆炸,而是 Spring 团队终于把很多企业开发的脏活继续收进框架里了。
这才是 Boot 最可怕的地方。
它不一定每次都发明新东西,但它会把你项目里那些重复配置、重复踩坑、重复封装的东西,一点点吃进标准能力里。吃着吃着,你就发现自己少写了一堆基础设施代码。
我的结论很简单:Spring Boot 4.1.0 开启的不是全新革命,而是 4.x 生产化能力的第一波大补强。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.