Reputation: 4714
I extend the RequestMappingHandlerMapping class by adding some features to it,
when I add my configuration like below:
@Configuration
public class MyConfig extends DelegatingWebMvcConfiguration {
@Override
@Bean
@Primary
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
return super.requestMappingHandlerMapping();
}
@Override
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
//Here I create my new version RequestMappingHandlerMapping
return new MyNewVersionRequestMappingHandlerMapping();
}
}
public class MyNewVersionRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
@Override
protected RequestCondition<?> getCustomTypeCondition(final Class<?> handlerType) {
// instead of null return my new Condition
return new SomeCustomTypeCondition(handlerType);
}
@Override
protected RequestCondition<?> getCustomMethodCondition(final Method method) {
// instead of null return my new Condition
return new SomeCustomTypeCondition(handlerType);
}
}
then start the application, it says:
The bean 'requestMappingHandlerMapping', defined in class path resource [com/test/MyConfig.class],
could not be registered. A bean with that name has already been defined in class path resource
[org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]
and overriding is disabled.
WebMvcAutoConfiguration.EnableWebMvcConfiguration has @Configuration annotation and extends from DelegatingWebMvcConfiguration:
public class WebMvcAutoConfiguration {
...
@Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
...
@Bean
@Primary
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
// I want return my version of RequestMappingHandlerMapping, but how?
return super.requestMappingHandlerMapping();
}
...
The chain of usage from spring-boot-autoconfigure-2.1.9.RELEASE.jar is:
-> META-INF\spring.factories
-> WebMvcAutoConfiguration
-> EnableWebMvcConfiguration
-> DelegatingWebMvcConfiguration.
So when use Spring Boot autoconfigure, it is coded to use DelegatingWebMvcConfiguration
, can I replace this default one my own version?
Certenly I can add the option to application.yml
main:
allow-bean-definition-overriding: true
It works. But I want to avoid doing so, because this option will hide bean duplication warnings.
So the question is: how to fix it without add such options?
Upvotes: 3
Views: 4593
Reputation: 29
I could make it work with following code. I hope problem solved for you.
package com.jjs.in.config;
@Configuration
public class WebConfigMapping extends DelegatingWebMvcConfiguration{
// @Configuration
// public static class UnconditionalWebMvcAutoConfiguration implements WebMvcConfigurer { // extends WebMvcAutoConfiguration {//forces @EnableWebMvc
// }
@Override
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
return new MyWebConfig.InternalPathRequestMappingHandlerMapping();
}
@Bean//("CASPER_REQUESTING_MAPPING")
@Primary
@Override
public RequestMappingHandlerMapping requestMappingHandlerMapping(
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
return super.requestMappingHandlerMapping(contentNegotiationManager, conversionService,resourceUrlProvider);
}
}
@Slf4j
@Configuration
public class MyWebConfig {
public static class InternalPathRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
@Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
RequestMappingInfo methodMapping = super.getMappingForMethod(method, handlerType);
if (methodMapping == null)
return null;
List<String> superclassUrlPatterns = new ArrayList<>();
for (Class<?> clazz = handlerType; clazz != Object.class; clazz = clazz.getSuperclass()) {
if (clazz.isAnnotationPresent(InternalRequest.class))
superclassUrlPatterns.add((String)methodMapping.getPatternsCondition().getPatterns().toArray()[0]);
}
if (method.isAnnotationPresent(InternalRequest.class) && superclassUrlPatterns.isEmpty()){
superclassUrlPatterns.add((String)methodMapping.getPatternsCondition().getPatterns().toArray()[0]);
}
if (!superclassUrlPatterns.isEmpty()) {
String newUrl = "MY_PREFIX"+ superclassUrlPatterns.get(0);
RequestMappingInfo superclassRequestMappingInfo = new RequestMappingInfo(methodMapping.getName(),
new PatternsRequestCondition(newUrl), methodMapping.getMethodsCondition()
, methodMapping.getParamsCondition()
, methodMapping.getHeadersCondition()
, methodMapping.getConsumesCondition()
, methodMapping.getProducesCondition()
, methodMapping.getCustomCondition());
return superclassRequestMappingInfo;
} else {
return methodMapping;
}
}
}
}
Upvotes: 3