Spring Boot 2.7升级3.2.0后Actuator端点返回500错误求助
问题背景
将Spring Boot服务从2.7升级到3.2.0后,访问9090端口的Actuator端点时出现HTTP Status 500 – Internal Server Error。堆栈跟踪显示,org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry.DispatcherServletDelegatingRequestMatcher#matcher方法中,this.servletContext.getServletRegistration(name)无法找到dispatcherServletRegistration,但访问8080端口的常规应用端点一切正常。
当前Actuator配置(仅更新了defaults部分,其余与2.7版本一致):
management: defaults: metrics: export: enabled: true endpoints: web: exposure: include: '*' info: build: enabled: true endpoint: health: show-details: when_authorized server: port: 9090
启动日志显示配置加载正常,但与新建Spring Initializer生成的3.2.0项目对比,当前应用未初始化9090端口对应的dispatcherServletRegistration,怀疑问题与Spring Security相关。
可能原因分析
Spring Security配置与Actuator独立端口的冲突
Spring Boot 3.x中,当Actuator使用独立端口(management.server.port)时,会创建独立的ServletContext和Web服务器实例。如果Spring Security配置仅针对主应用(8080端口)的全局上下文,未适配Actuator的独立Web上下文,就会导致在Actuator的ServletContext中找不到DispatcherServlet的注册信息。自定义DispatcherServlet配置未覆盖Actuator上下文
若项目中自定义了DispatcherServlet或DispatcherServletRegistrationBean,可能仅注册到了主应用的ServletContext(8080端口),未同步注册到Actuator的独立ServletContext中。Spring Boot 3.x Actuator Web上下文逻辑变更
Spring Boot 3.x对Actuator的Web上下文初始化逻辑做了调整,尤其是使用独立端口时,默认的DispatcherServlet注册逻辑可能被自定义配置干扰。
排查与解决建议
适配Spring Security到Actuator独立上下文
- 确保Spring Security配置类的
@Configuration未被限制仅作用于主应用上下文,避免@ConditionalOnWebApplication等注解排除Actuator的Web上下文。 - 为Actuator单独配置Security规则,比如自定义
SecurityFilterChain时指定匹配Actuator端点:@Bean public SecurityFilterChain actuatorSecurityFilterChain(HttpSecurity http) throws Exception { http.securityMatcher(EndpointRequest.toAnyEndpoint()); http.authorizeHttpRequests(auth -> auth.anyRequest().permitAll()); return http.build(); }
- 确保Spring Security配置类的
检查自定义DispatcherServlet注册逻辑
- 若存在自定义
DispatcherServletRegistrationBean,确认其作用域覆盖Actuator的Web上下文,而非仅主应用上下文。 - 临时移除自定义DispatcherServlet配置,测试是否恢复正常,以此判断是否为自定义配置导致的问题。
- 若存在自定义
验证Actuator Web上下文初始化日志
- 将日志级别调整为
DEBUG,查看org.springframework.boot.actuate.autoconfigure.web.servlet包下的日志,确认Actuator的Web上下文是否正确初始化DispatcherServlet。 - 对比新建Spring Initializer项目的启动日志,定位当前项目缺失的DispatcherServlet注册相关日志条目。
- 将日志级别调整为
检查Spring Boot 3.x迁移遗漏点
- 确认已完成Spring Security 6.x的迁移(Spring Boot 3.x对应Spring Security 6.x),比如已用
SecurityFilterChain替代废弃的WebSecurityConfigurerAdapter。 - 检查
management.server相关配置,比如management.server.base-path是否被自定义导致路径匹配异常。
- 确认已完成Spring Security 6.x的迁移(Spring Boot 3.x对应Spring Security 6.x),比如已用
临时禁用Actuator独立端口测试
- 注释掉
management.server.port配置,让Actuator使用主应用的8080端口,测试是否能正常访问。若正常,说明问题确实出在独立端口的Web上下文初始化环节。
- 注释掉
内容的提问来源于stack exchange,提问作者Micke

