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

如何在禁用Bean覆盖时重写Spring Boot的RequestMappingHandlerMapping?

解决Spring Boot中自定义RequestMappingHandlerMapping的Bean冲突问题

首先得明确为啥会触发这个报错:你通过继承DelegatingWebMvcConfiguration并重写requestMappingHandlerMapping()注册Bean的方式,和Spring Boot自动配置里WebMvcAutoConfiguration.EnableWebMvcConfiguration注册的同名Bean产生了冲突,而默认情况下Spring Boot不允许Bean定义覆盖,所以就抛出了这个异常。

其实不用开启allow-bean-definition-overriding来“掩盖”问题,Spring MVC早就给我们留了更优雅的扩展路径——实现WebMvcRegistrations接口,这个接口就是专门用来替换Spring MVC核心组件的,完全不会触发Bean冲突。

具体实现步骤:

  1. 实现WebMvcRegistrations接口,重写getRequestMappingHandlerMapping()方法返回你的自定义Handler Mapping:
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.config.annotation.WebMvcRegistrations;

public class CustomWebMvcRegistrations implements WebMvcRegistrations {
    @Override
    public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
        return new MyNewVersionRequestMappingHandlerMapping();
    }
}
  1. 在你的配置类里把这个实现类注册为Bean:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {
    @Bean
    public WebMvcRegistrations customWebMvcRegistrations() {
        return new CustomWebMvcRegistrations();
    }
}
  1. 顺便修正你自定义RequestMappingHandlerMapping里的小错误(之前getCustomMethodCondition里误用了不属于该方法的handlerType参数):
public class MyNewVersionRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
    @Override
    protected RequestCondition<?> getCustomTypeCondition(final Class<?> handlerType) {
        return new SomeCustomTypeCondition(handlerType);
    }

    @Override
    protected RequestCondition<?> getCustomMethodCondition(final Method method) {
        // 这里应该基于method参数创建对应的自定义Condition
        return new SomeCustomMethodCondition(method);
    }
}

为什么这个方法可行?

Spring Boot的WebMvcAutoConfiguration.EnableWebMvcConfiguration在创建RequestMappingHandlerMapping时,会优先检查容器中是否存在WebMvcRegistrations类型的Bean。如果存在,就会调用它的getRequestMappingHandlerMapping()方法获取实例,而不是使用默认实现。这样既完成了组件替换,又不会产生重复Bean的问题,完美避开了需要开启覆盖配置的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 10:44:05