首页
学习
活动
专区
圈层
工具
发布

DispatcherServlet之getHandlerAdapter

注: SpringFramework的版本是4.3.x。

1.DispatcherServlet的doService方法时序图

                                                        图1 DispatcherServlet的doService方法时序图

2.DispatcherServlet中默认会加载三个HandlerAdapter

    一般情况下,我们不会自己指定HandlerAdapter,所以只需要分析默认的情况。首先看DispatcherServlet的方法initHandlerAdapters(ApplicationContext context),该方法中加载文件DispatcherServlet.properties中指定的HandlerAdapter,如下图2所示,默认的HandlerAdapter有HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter、AnnotationMethodHandlerAdapter。

                                            图2 DispatcherServlet.properties指定的HandlerAdapter

2.1 HttpRequestHandlerAdapter

    HttpRequestHandlerAdapter类在spring-webmvc模块,类图如下图3所示,较为简单。

                                                      图3 HttpRequestHandlerAdapter的类图

    HttpRequestHandlerAdapter的源码如下List-1所示,由support的实现可知这个处理的情况是:controller类实现了接口HttpRequestHandler的情况。

List-1 HttpRequestHandlerAdapter的support和handle方法源码

代码语言:javascript
复制
public class HttpRequestHandlerAdapter implements HandlerAdapter {

	@Override
	public boolean supports(Object handler) {
		return (handler instanceof HttpRequestHandler);
	}

	@Override
	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		((HttpRequestHandler) handler).handleRequest(request, response);
		return null;
	}

	...
}

2.2 SimpleControllerHandlerAdapter

    SimpleControllerHandlerAdapter类在spring-webmvc模块中,它实现的HandlerAdapter接口是org.springframework.web.servlet.HandlerAdapter。

    SimpleControllerHandlerAdapter的部分源码如下List-2所示,由其support方法可知,这个类处理的是我们定义的controller类实现了org.springframework.web.servlet.mvc.Controller接口的情况。

List-2 SimpleControllerHandlerAdapter的support及其它方法源码

代码语言:javascript
复制
@Override
public boolean supports(Object handler) {
	return (handler instanceof Controller);
}

@Override
public void handleAction(ActionRequest request, ActionResponse response, Object handler)
		throws Exception {

	((Controller) handler).handleActionRequest(request, response);
}

@Override
public ModelAndView handleRender(RenderRequest request, RenderResponse response, Object handler)
		throws Exception {

	return ((Controller) handler).handleRenderRequest(request, response);
}
......

2.3 AnnotationMethodHandlerAdapter

    AnnotationMethodHandlerAdapter在spring-webmvc模块中,现在已经被Deprecated。

                                        图4 AnnotationMethodHandlerAdapter的类继承图

    AnnotationMethodHandlerAdapter的support方法及其它如下,一眼看上去比上面分析的俩个复杂多了。

List-3 AnnotationMethodHandlerAdapter的support方法及其它方法源码

代码语言:javascript
复制
@Override
public boolean supports(Object handler) {
	return getMethodResolver(handler).hasHandlerMethods();
}

@Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
		throws Exception {
	Class<?> clazz = ClassUtils.getUserClass(handler);
	Boolean annotatedWithSessionAttributes = this.sessionAnnotatedClassesCache.get(clazz);
	if (annotatedWithSessionAttributes == null) {
		annotatedWithSessionAttributes = (AnnotationUtils.findAnnotation(clazz, SessionAttributes.class) != null);
		this.sessionAnnotatedClassesCache.put(clazz, annotatedWithSessionAttributes);
	}

	if (annotatedWithSessionAttributes) {
		checkAndPrepare(request, response, this.cacheSecondsForSessionAttributeHandlers, true);
	}
	else {
		checkAndPrepare(request, response, true);
	}
	// Execute invokeHandlerMethod in synchronized block if required.
	if (this.synchronizeOnSession) {
		HttpSession session = request.getSession(false);
		if (session != null) {
			Object mutex = WebUtils.getSessionMutex(session);
			synchronized (mutex) {
				return invokeHandlerMethod(request, response, handler);
			}
		}
	}
	return invokeHandlerMethod(request, response, handler);
}
......

    来看下AnnotationMethodHandlerAdapter的support方法时序图,原图在Github上。

                                       图5 AnnotationMethodHandlerAdapter的support时序图

(adsbygoogle = window.adsbygoogle || []).push({});

下一篇
举报
领券