springMVC源码分析--HandlerMethod
在之前的博客中我们已经接触过HandlerMethod,接下来我们简单介绍一下HandlerMethod,简单来说HandlerMethod包含的信息包括类、方法和参数的一个信息类,通过其两个构造函数我们就可以了解其功能,对应着springMVC的Controller来说就是某个url对应的某个Controller执行的方法。
/** * Create an instance from a bean instance and a method. */ public HandlerMethod(Object bean, Method method) { Assert.notNull(bean, "Bean is required"); Assert.notNull(method, "Method is required"); this.bean = bean; this.beanFactory = null; this.beanType = ClassUtils.getUserClass(bean); this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); this.parameters = initMethodParameters(); this.resolvedFromHandlerMethod = null; }
/** * Create an instance from a bean instance, method name, and parameter types. * @throws NoSuchMethodException when the method cannot be found */ public HandlerMethod(Object bean, String methodName, Class<?>... parameterTypes) throws NoSuchMethodException { Assert.notNull(bean, "Bean is required"); Assert.notNull(methodName, "Method name is required"); this.bean = bean; this.beanFactory = null; this.beanType = ClassUtils.getUserClass(bean); this.method = bean.getClass().getMethod(methodName, parameterTypes); this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(this.method); this.parameters = initMethodParameters(); this.resolvedFromHandlerMethod = null; }
完整源码如下:
public class HandlerMethod { /** Logger that is available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); private final Object bean; private final BeanFactory beanFactory; private final Class<?> beanType; private final Method method; private final Method bridgedMethod; private final MethodParameter[] parameters; private final HandlerMethod resolvedFromHandlerMethod; //创建一个实例,根据bean实例和method方法 public HandlerMethod(Object bean, Method method) { Assert.notNull(bean, "Bean is required"); Assert.notNull(method, "Method is required"); this.bean = bean; this.beanFactory = null; this.beanType = ClassUtils.getUserClass(bean); this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); this.parameters = initMethodParameters(); this.resolvedFromHandlerMethod = null; } //根据bean,方法名以及参数类型创建实例 public HandlerMethod(Object bean, String methodName, Class<?>... parameterTypes) throws NoSuchMethodException { Assert.notNull(bean, "Bean is required"); Assert.notNull(methodName, "Method name is required"); this.bean = bean; this.beanFactory = null; this.beanType = ClassUtils.getUserClass(bean); this.method = bean.getClass().getMethod(methodName, parameterTypes); this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(this.method); this.parameters = initMethodParameters(); this.resolvedFromHandlerMethod = null; } //根据bean名称,BeanFactory工厂和method方法创建实例 public HandlerMethod(String beanName, BeanFactory beanFactory, Method method) { Assert.hasText(beanName, "Bean name is required"); Assert.notNull(beanFactory, "BeanFactory is required"); Assert.notNull(method, "Method is required"); this.bean = beanName; this.beanFactory = beanFactory; this.beanType = ClassUtils.getUserClass(beanFactory.getType(beanName)); this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); this.parameters = initMethodParameters(); this.resolvedFromHandlerMethod = null; } protected HandlerMethod(HandlerMethod handlerMethod) { Assert.notNull(handlerMethod, "HandlerMethod is required"); this.bean = handlerMethod.bean; this.beanFactory = handlerMethod.beanFactory; this.beanType = handlerMethod.beanType; this.method = handlerMethod.method; this.bridgedMethod = handlerMethod.bridgedMethod; this.parameters = handlerMethod.parameters; this.resolvedFromHandlerMethod = handlerMethod.resolvedFromHandlerMethod; } private HandlerMethod(HandlerMethod handlerMethod, Object handler) { Assert.notNull(handlerMethod, "HandlerMethod is required"); Assert.notNull(handler, "Handler object is required"); this.bean = handler; this.beanFactory = handlerMethod.beanFactory; this.beanType = handlerMethod.beanType; this.method = handlerMethod.method; this.bridgedMethod = handlerMethod.bridgedMethod; this.parameters = handlerMethod.parameters; this.resolvedFromHandlerMethod = handlerMethod; } private MethodParameter[] initMethodParameters() { int count = this.bridgedMethod.getParameterTypes().length; MethodParameter[] result = new MethodParameter[count]; for (int i = 0; i < count; i++) { result[i] = new HandlerMethodParameter(i); } return result; } public Object getBean() { return this.bean; } public Method getMethod() { return this.method; } public Class<?> getBeanType() { return this.beanType; } protected Method getBridgedMethod() { return this.bridgedMethod; } public MethodParameter[] getMethodParameters() { return this.parameters; } public HandlerMethod getResolvedFromHandlerMethod() { return this.resolvedFromHandlerMethod; } public MethodParameter getReturnType() { return new HandlerMethodParameter(-1); } public MethodParameter getReturnValueType(Object returnValue) { return new ReturnValueMethodParameter(returnValue); } public boolean isVoid() { return Void.TYPE.equals(getReturnType().getParameterType()); } //获取方法上的注解,单个注解,如果没有注解则返回方法本身 public <A extends Annotation> A getMethodAnnotation(Class<A> annotationType) { return AnnotatedElementUtils.findMergedAnnotation(this.method, annotationType); } //创建handlerMethod public HandlerMethod createWithResolvedBean() { Object handler = this.bean; if (this.bean instanceof String) { String beanName = (String) this.bean; handler = this.beanFactory.getBean(beanName); } return new HandlerMethod(this, handler); } @Override public boolean equals(Object other) { if (this == other) { return true; } if (!(other instanceof HandlerMethod)) { return false; } HandlerMethod otherMethod = (HandlerMethod) other; return (this.bean.equals(otherMethod.bean) && this.method.equals(otherMethod.method)); } @Override public int hashCode() { return (this.bean.hashCode() * 31 + this.method.hashCode()); } @Override public String toString() { return this.method.toGenericString(); } /** * A MethodParameter with HandlerMethod-specific behavior. */ protected class HandlerMethodParameter extends SynthesizingMethodParameter { public HandlerMethodParameter(int index) { super(HandlerMethod.this.bridgedMethod, index); } @Override public Class<?> getContainingClass() { return HandlerMethod.this.getBeanType(); } @Override public <T extends Annotation> T getMethodAnnotation(Class<T> annotationType) { return HandlerMethod.this.getMethodAnnotation(annotationType); } } /** * A MethodParameter for a HandlerMethod return type based on an actual return value. */ private class ReturnValueMethodParameter extends HandlerMethodParameter { private final Object returnValue; public ReturnValueMethodParameter(Object returnValue) { super(-1); this.returnValue = returnValue; } @Override public Class<?> getParameterType() { return (this.returnValue != null ? this.returnValue.getClass() : super.getParameterType()); } } }
springMVC源码分析--HandlerMethod的更多相关文章
- springMVC源码分析--访问请求执行ServletInvocableHandlerMethod和InvocableHandlerMethod
在之前一篇博客中springMVC源码分析--RequestMappingHandlerAdapter(五)我们已经简单的介绍到具体请求访问的执行某个Controller中的方法是在RequestMa ...
- springMVC源码分析--AbstractHandlerMethodMapping注册url和HandlerMethod对应关系(十一)
在上一篇博客springMVC源码分析--AbstractHandlerMethodMapping获取url和HandlerMethod对应关系(十)中我们简单地介绍了获取url和HandlerMet ...
- springMVC源码分析--AbstractHandlerMethodMapping获取url和HandlerMethod对应关系(十)
在之前的博客springMVC源码分析--AbstractHandlerMapping(二)中我们介绍了AbstractHandlerMethodMapping的父类AbstractHandlerMa ...
- 8、SpringMVC源码分析(3):分析ModelAndView的形成过程
首先,我们还是从DispatcherServlet.doDispatch(HttpServletRequest request, HttpServletResponse response) throw ...
- 7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解
从上一篇 SpringMVC源码分析(1) 中我们了解到在DispatcherServlet.doDispatch方法中会通过 mv = ha.handle(processedRequest, res ...
- springMVC源码分析--RequestMappingHandlerAdapter(五)
上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...
- springMVC源码分析--AbstractHandlerMapping(二)
上一篇博客springMVC源码分析--HandlerMapping(一)中我们简单的介绍了HandlerMapping,接下来我们介绍一下它的抽象实现类AbstractHandlerMapping
- springMVC源码分析--HandlerMapping(一)
HandlerMapping的工作就是为每个请求找到合适的请求找到一个处理器handler,其实现机制简单来说就是维持了一个url到Controller关系的Map结构,其提供的实际功能也是根据req ...
- springMVC源码分析--拦截器HandlerExecutionChain(三)
上一篇博客springMVC源码分析--HandlerInterceptor拦截器调用过程(二)中我们介绍了HandlerInterceptor的执行调用地方,最终HandlerInterceptor ...
随机推荐
- MySQL · 引擎特性 · InnoDB 同步机制
前言 现代操作系统以及硬件基本都支持并发程序,而在并发程序设计中,各个进程或者线程需要对公共变量的访问加以制约,此外,不同的进程或者线程需要协同工作以完成特征的任务,这就需要一套完善的同步机制,在Li ...
- kafka知识体系-kafka设计和原理分析-kafka leader选举
kafka leader选举 一条消息只有被ISR中的所有follower都从leader复制过去才会被认为已提交.这样就避免了部分数据被写进了leader,还没来得及被任何follower复制就宕机 ...
- 【swift,oc】ios开发中巧用自动布局设置自定义cell的高度
ios开发中,遇到自定义高度不定的cell的时候,我们通常的做法是抽取一个frame类,在frame类中预算好高度,再返回. 但是苹果出来自动布局之后...春天来了!!来看看怎么巧用自动布局设置自定义 ...
- 计蒜客NOIP模拟赛5 D1T1 机智的 AmyZhi
那年一个雨季,AmyZhi 在校门外弯身买参考书. 这时 SiriusRen 走过来,一言不合甩给她一道“自认为”很难的题: --------------- 给你一个数字 NN(NN 的范围是 11 ...
- ●POJ 1741 Tree
题链: http://poj.org/problem?id=1741题解: 树上点分治. 入门题,不多说了. 代码: #include<cstdio> #include<cstrin ...
- ●BZOJ 1396 识别子串
题链: http://www.joyoi.cn/problem/tyvj-2301(非权限OI患者,苟且在joyoi...)题解: 后缀自动机,线段树 先对原串建立后缀自动机,不难发现, 会影响答案是 ...
- ●BOZJ 4456 [Zjoi2016]旅行者
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4456 题解: 分治好题.大致做法如下:对于一开始的矩形区域,过较长边的中点把矩形区域分为两个 ...
- 【CodeVs 6128 Lence的方块们】
·希望除了内部人员以外能有人通过这道题,因为这是大米饼第一次改编的题 ·我所见到的"本题原版"的题解也很少,搜索一下应该是: #include<stdio.h> #in ...
- poj 3693 后缀数组 重复次数最多的连续重复子串
Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 8669 Acc ...
- Codeforces Round#403 (Div. 1)
唉,昨天晚上迷迷糊糊地去打cf,结果fst两题,掉回蓝了... A.Andryusha and Colored Balloons 题意:给定一棵树,任意两个距离小等于二的点不能染相同的颜色,求最小颜色 ...