在之前的博客中我们已经接触过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的更多相关文章

  1. springMVC源码分析--访问请求执行ServletInvocableHandlerMethod和InvocableHandlerMethod

    在之前一篇博客中springMVC源码分析--RequestMappingHandlerAdapter(五)我们已经简单的介绍到具体请求访问的执行某个Controller中的方法是在RequestMa ...

  2. springMVC源码分析--AbstractHandlerMethodMapping注册url和HandlerMethod对应关系(十一)

    在上一篇博客springMVC源码分析--AbstractHandlerMethodMapping获取url和HandlerMethod对应关系(十)中我们简单地介绍了获取url和HandlerMet ...

  3. springMVC源码分析--AbstractHandlerMethodMapping获取url和HandlerMethod对应关系(十)

    在之前的博客springMVC源码分析--AbstractHandlerMapping(二)中我们介绍了AbstractHandlerMethodMapping的父类AbstractHandlerMa ...

  4. 8、SpringMVC源码分析(3):分析ModelAndView的形成过程

    首先,我们还是从DispatcherServlet.doDispatch(HttpServletRequest request, HttpServletResponse response) throw ...

  5. 7、SpringMVC源码分析(2):分析HandlerAdapter.handle方法,了解handler方法的调用细节以及@ModelAttribute注解

    从上一篇 SpringMVC源码分析(1) 中我们了解到在DispatcherServlet.doDispatch方法中会通过 mv = ha.handle(processedRequest, res ...

  6. springMVC源码分析--RequestMappingHandlerAdapter(五)

    上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...

  7. springMVC源码分析--AbstractHandlerMapping(二)

    上一篇博客springMVC源码分析--HandlerMapping(一)中我们简单的介绍了HandlerMapping,接下来我们介绍一下它的抽象实现类AbstractHandlerMapping

  8. springMVC源码分析--HandlerMapping(一)

    HandlerMapping的工作就是为每个请求找到合适的请求找到一个处理器handler,其实现机制简单来说就是维持了一个url到Controller关系的Map结构,其提供的实际功能也是根据req ...

  9. springMVC源码分析--拦截器HandlerExecutionChain(三)

    上一篇博客springMVC源码分析--HandlerInterceptor拦截器调用过程(二)中我们介绍了HandlerInterceptor的执行调用地方,最终HandlerInterceptor ...

随机推荐

  1. js常用的字符串方法分析

    ##字符串## 字符串: 由0个或多个字符组成,被成对的英文单引号或双引号包含起来的. 字符编码: 每一个字符在计算机存储的编号. 计算机会保存有一套或几套用于标注编号与字符对应关系的字典.(字符集) ...

  2. ios开发- 利用运行时(runtime)字典转模型

    现在的ios开发中,我们通常会使用MVC模式.当我们拿到数据的时候,我们要把数据转成模型使用. 一般情况我们拿到的数据都是字典.这是我们就需要将字典转成模型对象了. 当对象的属性很少的时候,我们可以直 ...

  3. [POI 2015]Kinoman

    Description 共有m部电影,编号为1~m,第i部电影的好看值为w[i]. 在n天之中(从1~n编号)每天会放映一部电影,第i天放映的是第f[i]部. 你可以选择l,r(1<=l< ...

  4. ●BZOJ 4407 于神之怒加强版

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4407 题解: 莫比乌斯反演 直接套路化式子 $\begin{align*}ANS&= ...

  5. ●线段树的三个题(poj 3225,hdu 1542,hdu 1828)

    ●poj 3225 Help with Intervals(线段树区间问题) ○赘述题目 给出以下集合操作: 然后有初始的一个空集S,和以下题目给出的操作指令,并输入指令: 要求进行指令操作后,按格式 ...

  6. 2015 多校联赛 ——HDU5353(构造)

    Each soda has some candies in their hand. And they want to make the number of candies the same by do ...

  7. [BZOJ]1005 明明的烦恼(HNOI2008)

    BZOJ的第一页果然还是很多裸题啊,小C陆续划水屯些板子. Description 自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在任意两点间 ...

  8. 作为开发也要了解的 mysql 优化思路

    作为开发人员,数据库知识掌握的可能不是很深入,但是一些基本的技能还是要有时间学习一下的.作为一个数据库菜鸟,厚着脸皮来总结一下 mysql 的基本的不能再基本的优化方法. 为了更好的说明,我假想出来了 ...

  9. django rest-framework 4.REST的认证和权限

    目前,我们的API对谁可以编辑或删除代码段没有任何限制.我们想要一些更先进的行为,以确保:(这段话抄自官网) 代码段始终与创建者相关联. 只有身份验证的用户可以创建片段. 只有片段的创建者可以更新或删 ...

  10. Cookie 和 Session的基本使用

    cookie: 放在客户端上的键值对. 1.设置cookie obj = render(request,'index.html') obj.set_cookie('key','value') retu ...