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 ...
随机推荐
- javascript 错误处理和堆栈追踪浅析
合理地处理堆栈信息能使你清除无用的数据, 而只专注于有用的数据. 同时, 当更好地理解 Errors 对象及其相关属性之后, 能有助于你更充分地利用 Errors. (函数的)调用栈是怎么工作的 在谈 ...
- 原生http请求封装
满血复活,今天开始开始更新博客.随着es6的普遍应用,promise属性也随之用之普遍,我们在一些项目中,为了避免引入一些http库,节省空间,就简单将原生http请求做了封装处理,封装代码如下:(其 ...
- [HNOI 2015]接水果
Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果. 由于她已经DT FC 了The big black, 她觉得这个游戏太简单了,于是发明了一个更 ...
- [BZOJ]1064: [Noi2008]假面舞会
题目大意:n个人,k种假面,每人戴一种,戴第i种的可以看见第i+1种,戴第k种的可以看见第1种,给出m条关系表示一个人可以看到另一个人,问k可能的最大值和最小值.(n<=100,000,m< ...
- NOIP2014-9-6模拟赛
工资 (money/money.in/money.out) 时限1000ms 内存256MB 聪哥在暑假参加了打零工的活动,这个活动分为n个工作日,每个工作日的工资为Vi.有m个结算工钱的时间,聪哥可 ...
- hdu4542 && ZOJ2562(反素数)
反素数: 对于任何正整数,其约数个数记为,例如,如果某个正整数满足:对任意的正整 数,都有,那么称为反素数. 有两个特点: 1.一个反素数的质因子必是从2开始的质数 2.如果,那么必有 最常见的问题如 ...
- 【UOJ UNR #1】争夺圣杯
来自FallDream的博客,未经允许,请勿转载,谢谢. 传送门 考虑直接对每个数字,统计它会产生的贡献. 单调栈求出每个数字左边第一个大等于他的数,右边第一个大于他的 (注意只能有一边取等) 假设左 ...
- [USACO08JAN]跑步Running
题目描述 The cows are trying to become better athletes, so Bessie is running on a track for exactly N (1 ...
- HL7工具安装步骤
下载目录:http://gforge.hl7.org/gf/ 说明:在安装HL7V3学习工具之前,确保本机已安装IIS服务和Access数据库. 各种软件见附件. 1.下载安装步骤 RIM模型下载 ...
- RTX 无法刷新组织架构的处理方法总结
文章一: 刷新组织架构问题1."客户端不能获取正确的组织架构"或"新增加的人员刷新不了组织架构"首先要判断是RTX服务器引起的异常还是一些客户端出现的异常,判断 ...