spring-boot: Unable to have custom RequestMappingHandlerMapping
I want to override the default RequestMappingHandlerMapping as follows:
@Configuration
public static class VersionConfig extends WebMvcConfigurationSupport {
@Override
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
return new VersionRequestMappingHandlerMapping();
}
}
where VersionRequestMappingHandlerMapping simply overrides some stub methods:
@Component
public class VersionRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
@Override protected RequestCondition<?> getCustomTypeCondition(Class<?> handlerType) {
VersionRange typeAnnotation = AnnotationUtils.findAnnotation(handlerType, VersionRange.class);
return (typeAnnotation != null) ? new VersionRangeRequestCondition(typeAnnotation.value()) : null;
}
@Override
protected RequestCondition<?> getCustomMethodCondition(Method method) {
VersionRange methodAnnotation = AnnotationUtils.findAnnotation(
method, VersionRange.class);
return (methodAnnotation != null) ? new VersionRangeRequestCondition(methodAnnotation.value()) : null;
}
}
The issue is that because I am extending WebMvcConfigurationSupport in my config, WebMvcAutoConfiguration fails it’s conditional:
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
public class WebMvcAutoConfiguration {
I think the main issue is that the method :
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
in WebMvcConfigurationSupport does too much work in the sense that it doesn’t simply create a new instance of RequestMappingHandlerAdapter so if I had to create my own @Bean returning a RequestMappingHandlerAdapter I would have to paste large chunks of code from WebMvcConfigurationSupport. If we had some factory available, I would just override that to inject my version instead.
There was a similar discussion reported on http://stackoverflow.com/questions/22267191/is-it-possible-to-extend-webmvcconfigurationsupport-and-use-webmvcautoconfigurat but the workaround only worked because it is invoking methods on the existing bean, not overriding them like in my case.
I’m willing to attempt a patch but I’d rather take up some comments/suggestions first.
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 16 (10 by maintainers)
Commits related to this issue
- Add WebMvcRegistrations for custom MVC components Prior to this commit, developers could provide their custom instances of MVC infrstructure components such as `RequestMappingHandlerMapping` and `Req... — committed to bclozel/spring-boot by bclozel 8 years ago
- Add WebMvcRegistrations for custom MVC components Prior to this commit, developers could provide their custom instances of MVC infrstructure components such as `RequestMappingHandlerMapping` and `Req... — committed to bclozel/spring-boot by bclozel 8 years ago
- Add WebMvcRegistrations for custom MVC components Prior to this commit, developers could provide their custom instances of MVC infrstructure components such as `RequestMappingHandlerMapping` and `Req... — committed to philwebb/spring-boot by bclozel 8 years ago
- Add WebMvcRegistrations for custom MVC components Prior to this commit, developers could provide their custom instances of MVC infrstructure components such as `RequestMappingHandlerMapping` and `Req... — committed to philwebb/spring-boot by bclozel 8 years ago
Thanks for the reply. Could you please provide any pointers for how to currently configure a spring boot application to provide everything that WebMvcAutoConfiguration provides but use a custom RequestMappingHandlerMapping? I mean is there anything better than just copying the entire existing WebMvcAutoConfiguration into a new class, modifying it, and registering it as an auto configuration?
I’ve gone ahead and added a couple more protected methods (https://github.com/spring-projects/spring-framework/commit/ebccfd023a7c7bb862bff96796310d8a35305f87) to allow plugging in custom sub-classes.
After giving this some more thought here is the way I see this. At the lowest level the Spring Framework provides two modes of MVC Java config. A simple callback-based configuration API (i.e.
WebMvcConfigurer) that does not require seeing or knowing what beans are behind it and a more advanced option to extend directly from the bean-providing configuration (i.e.WebMvcConfigurationSupport). A user can choose one of these two modes.Boot as an opinionated user chooses the advanced option which still allows applications to exercise control via one or more
WebMvcConfigurerconfig classes. When a Boot user wants to do more advanced things they can extend Boot’s own WebMvcAutoConfiguration which could be a top-level class calledBootWebMvcConfigurationSupport. Furthermore Boot can detect and hook in custom sub-classes ofRequestMappingHandlerMapping,RequestMappingHandlerAdapter, andExceptionHandlerExceptionResolverso that switching to advanced configuration is not needed.I think this model would make the most sense in terms of what’s expected on each level. At the Spring MVC level we can continue to make sure what needs to be extensible is. At the Spring Boot level we can then automatically detect user-provided custom sub-classes.
@michaelkrog unfortunately this will turn off all Spring Boot auto-configuration for Spring MVC and defeats the purpose of this issue. I believe this should still work in Spring Boot 2.0+:
If it doesn’t, please open a new issue with a small project reproducing the error. Thanks!