【问题标题】:Is it possible to extend WebMvcConfigurationSupport and use WebMvcAutoConfiguration?是否可以扩展 WebMvcConfigurationSupport 并使用 WebMvcAutoConfiguration?
【发布时间】:2014-04-11 14:38:02
【问题描述】:

我还需要扩展 WebMvcConfigurationSupport 类修改两件事:

@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
    @Override
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        RequestMappingHandlerMapping handlerMapping = super.requestMappingHandlerMapping();
        handlerMapping.setRemoveSemicolonContent(false);
        handlerMapping.setOrder(1);
        return handlerMapping;
    }
}

我喜欢从 WebMvcAutoConfiguration 类注册的默认值,但由于类上的条件注释,当我扩展 WebMvcConfigurationSupport 类时,它会阻止自动配置发生。

@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
    WebMvcConfigurerAdapter.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@Order(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter(DispatcherServletAutoConfiguration.class)
public class WebMvcAutoConfiguration {...}

是否可以加载 WebMvcAutoConfiguration 类而无需复制/粘贴该类中的大部分代码?

或者是否可以从其他地方调用 RequestMappingHandlerMapping setOrder() 和 setRemoveSemicolonContent(),这样我就可以使用 @EnableWebMvc 注释并让自动配置类运行没有任何问题?

提前致谢!

【问题讨论】:

    标签: java spring spring-mvc spring-boot


    【解决方案1】:

    从DelegatingWebMvcConfiguration 扩展而不是WebMvcConfigurationSupport,它不会阻止自动配置发生:

    @Configuration
    public class WebConfig extends DelegatingWebMvcConfiguration {
        @Override
        public RequestMappingHandlerMapping requestMappingHandlerMapping() {
            RequestMappingHandlerMapping handlerMapping = super.requestMappingHandlerMapping();
            handlerMapping.setRemoveSemicolonContent(false);
            handlerMapping.setOrder(1);
            return handlerMapping;
        }
    }
    

    【讨论】:

    • 它忽略了我的自动配置..不确定它对其他人的工作方式
    【解决方案2】:

    我设法自定义 RequestMappingHandlerMapping,同时使用 BeanPostProcessor 保留 WebMvcAutoConfiguration:

    @Configuration
    public class RequestMappingConfiguration {
        @Bean
        public RequestMappingHandlerMappingPostProcessor requestMappingHandlerMappingPostProcessor() {
            return new RequestMappingHandlerMappingPostProcessor();
        }
    
        public static class RequestMappingHandlerMappingPostProcessor implements BeanPostProcessor {
    
            @Override
            public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
                if (bean instanceof RequestMappingHandlerMapping) {
                    ((RequestMappingHandlerMapping) bean).setUseSuffixPatternMatch(false);
                }
                return bean;
            }
    
            @Override
            public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
                return bean;
            }
        }
    }
    

    如果 Spring Boot 提供了一种更好的方法来处理这个问题,我会很高兴...也许可以在 PathMatchConfigurer 周围做点什么?

    【讨论】:

    • 我发现这个解决方案适用于应用程序中定义了 SpringFox Swagger Docket 的情况。上面使用 DelegatingWebMvcConfiguration 的解决方案会导致 swagger doc 显示失败。
    • 不错的解决方案。但是你能不能在这里直接将RequestMappingHandlerMappingPostProcessor 声明为@Configuration ?
    【解决方案3】:

    您的分析是正确的(@EnableWebMvc 或直接扩展WebMvcConfigurationSupport 将关闭WebMvcAutoConfiguration)。我不确定替代方案是什么,因为a)我们需要一个自动配置的“退出”子句,b)我认为Spring不喜欢在同一上下文中有两个WebMvcConfigurationSupports。如果你想尝试改变它,很高兴在 github 上讨论(可能有一些中间立场)。

    【讨论】:

    • 感谢戴夫的快速回复!我仍然对 Spring Boot 有点陌生(一般是 Spring tbh)......我开始创建一个新的 SimpleUrlHandlerMapping bean,因为我注意到 DispatchServlet 抓取了所有 HandlerMapping 类型的 bean,但我有点转身围绕创建 ResourceHttpRequestHandler,并放下一些东西。我会看看我是否能找到一些不那么 hacky 的东西,或者把它扔在这里或 Github 上,也许是一种更简单的注入和订购 HandlerMapping bean 的方法,我将不得不戳一下它。谢谢!
    • 对于您特定的狭窄用例,我认为添加@Bean 类型的RequestMappingHandlerMapping 就足够了(从WebMvcConfigurationSupport 复制代码)。您需要它的顺序低于默认顺序(这引出了一个问题:为什么在自定义映射中使用 order=1?)。
    • 我也一直在这个问题上挑战自己。我的用例涉及将未确定的请求映射到“包罗万象”的 ant 样式映射,例如 /** 意图是任何具有更高特异性的映射都将首先被映射,这是带注释的控制器的情况,但不是资源处理程序的情况。目标是在不丢失 /** 样式映射的情况下将资源处理程序的优先级降低到注释控制器之下。实际上,我一直在使用@Bean 处理程序映射的想法,所以我认为这是正确的方法,谢谢!
    【解决方案4】:

    我认为现在在 Spring Boot 中执行此操作的最佳方法是将 WebMvcRegistrations 组件添加到您的上下文中 - 在您提出问题时此解决方案不存在(自 Spring Boot 1.4.0 起就可用) .

    【讨论】:

    • 这在异常处理程序的情况下仍然非常有限,因为它只允许覆盖 ExceptionHandlerExceptionResolver,我们感兴趣的是之后添加的默认值。
    猜你喜欢
    • 2015-04-11
    • 2010-12-21
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    相关资源
    最近更新 更多