1、为什么要重写
- 在项目开发中,有一次一个需求涉及到修改几个方法,需要在这几个方法中添加自己的业务逻辑,这几个方法是标有@RequestMapping注解的方法,而且这几个方法在封装好的底层jar包中,那么如何修改呢?
- 思路:1、首先想到的是通过重新在controller层自定义一个url,然后对底层的对应方法进行一个重写操作,这样是可以解决问题,但是如果这样修改,前端接入的url也要配合修改,这样就增加了一定工作量,当后续修改更多这样的底层url后,对接也会变得复杂,所以该方案可行,但是不够优雅;2、之前了解过springmvc源码,知道工作的大致原理,所以我想到是否可以自定义一个RequestMapping注解,实现类似于RequestMapping的功能,然后将该注解的url与底层jar包中要需要改写的方法的url一样,这样前端就不用修改url,只需要后端重新方法逻辑即可。
2、如何重写
- 首先要知道springmvc中定义的RequestMapping注解的处理类RequestMappingHandlerMapping,该类中可以看到有如下方法处理RequestMapping注解
// method处理的方法
// handlerType处理器类型,一般就是指controller层的类
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
// 将method方法上的@RequestMapping注解中的值取出
RequestMappingInfo info = createRequestMappingInfo(method);
if (info != null) {
// 将handlerType类上的@RequestMapping注解中的值取出
RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);
if (typeInfo != null) {
// 拼接类上的@RequestMapping注解中的路径与方法上的@RequestMapping注解中的路径
info = typeInfo.combine(info);
}
String prefix = getPathPrefix(handlerType);
if (prefix != null) {
info = RequestMappingInfo.paths(prefix).build().combine(info);
}
}
return info;
}
private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
// 获取该方法上面的RequestMapping注解
RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
RequestCondition<?> condition = (element instanceof Class ?
getCustomTypeCondition((Class<?>) element) : getCustomMethodCondition((Method) element));
return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);
}
// 将RequestMapping中的值封装到RequestMappingInfo对象中
protected RequestMappingInfo createRequestMappingInfo(
RequestMapping requestMapping, @Nullable RequestCondition<?> customCondition) {
RequestMappingInfo.Builder builder = RequestMappingInfo
.paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
.methods(requestMapping.method())
.params(requestMapping.params())
.headers(requestMapping.headers())
.consumes(requestMapping.consumes(