You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3.0调用ServerHttpResponse.setStatusCode引发ClassLoader问题

Spring Boot 2.7.X 迁移至3.0.X后ServerHttpResponse方法调用导致启动失败的解决方法

我在将Spring Boot从2.7.X版本迁移至3.0.X版本时,遇到应用无法正常启动的异常。示例代码如下:

public class ExampleFilter implements WebFilter {

    @Override
    @NonNull
    public Mono<Void> filter(ServerWebExchange exchange, @NonNull WebFilterChain chain) {
        var response = exchange.getResponse();
        response.setStatusCode(HttpStatus.METHOD_NOT_ALLOWED);
        return chain.filter(exchange);

    }
}

抛出的异常栈信息:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'allowedMethodsFilter': Lookup method resolution failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [tmp.AllowedMethodsFilter] from ClassLoader [org.springframework.boot.loader.LaunchedURLClassLoader@7eda2dbb]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:289)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineConstructorsFromBeanPostProcessors(AbstractAutowireCapableBeanFactory.java:1302)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1219)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
    at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:64)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:745)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:420)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
    at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:164)
    at tmp.ExampleApp.main(ExampleApp.java:21)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)
Caused by: java.lang.IllegalStateException: Failed to introspect Class [tmp.AllowedMethodsFilter] from ClassLoader [org.springframework.boot.loader.LaunchedURLClassLoader@7eda2dbb]
    at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:485)
    at org.springframework.util.ReflectionUtils.doWithLocalMethods(ReflectionUtils.java:321)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:267)
    ... 25 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/springframework/http/HttpStatusCode
    at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
    at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3402)
    at java.base/java.lang.Class.getDeclaredMethods(Class.java:2504)
    at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:467)
    ... 27 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.http.HttpStatusCode
    at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:587)
    at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    ... 31 common frames omitted

所有使用ServerHttpResponse的setStatusCode/getStatusCode方法的地方都会引发类似问题。


问题原因

  1. API重构与依赖版本不一致:Spring Framework 6.0(对应Spring Boot 3.0)引入了HttpStatusCode接口作为状态码的统一抽象,ServerHttpResponse的setStatusCode方法参数类型从HttpStatus改为HttpStatusCode。如果项目中存在混合Spring 5.x和6.x版本的依赖,会导致HttpStatusCode类找不到的异常。
  2. Reactive逻辑不规范:设置响应状态码后继续调用chain.filter(exchange)会导致响应生命周期冲突,不符合Reactive Web的处理规范。
  3. 过滤器命名冲突:自定义过滤器名称allowedMethodsFilter可能与Spring Boot自动配置的过滤器重名,引发Bean初始化异常。

解决方案

1. 统一升级所有Spring相关依赖版本

检查项目依赖配置(Maven pom.xml/Gradle build.gradle),确保所有Spring Framework、Spring WebFlux等依赖的版本与Spring Boot 3.0完全对齐,避免混合不同版本的依赖。

2. 调整API调用方式(兼容新规范)

虽然HttpStatus实现了HttpStatusCode接口,直接传入HttpStatus.METHOD_NOT_ALLOWED语法上可行,但如果仍有问题,可显式转换:

response.setStatusCode(HttpStatusCode.valueOf(HttpStatus.METHOD_NOT_ALLOWED.value()));

3. 修正过滤器逻辑(符合Reactive规范)

设置响应状态码后,应直接返回完成信号终止请求处理,不再执行后续过滤器链:

public class ExampleFilter implements WebFilter {

    @Override
    @NonNull
    public Mono<Void> filter(ServerWebExchange exchange, @NonNull WebFilterChain chain) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.METHOD_NOT_ALLOWED);
        // 直接结束请求处理
        return response.setComplete();
    }
}

4. 避免过滤器命名冲突

修改自定义过滤器的Bean名称,避免与Spring自动配置的过滤器重名:

@Bean
public WebFilter exampleFilter() {
    return new ExampleFilter();
}

内容的提问来源于stack exchange,提问作者huhala

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 15:35:20