从DispatcherServlet到HandlerAdapter

tomcat启动时,DispatcherServlet初始化HandlerAdapter,默认加载的处理适配器有:org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter、org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter和org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter及自定义HandlerAdapter。对于spring来说还会加载org.springframework.web.HttpRequestHandler和org.springframework.web.servlet.mvc.Controller。

HandlerAdapter及其实现中有三个方法:supports(java.lang.Object handler),handle(HttpServletRequest request, HttpServletResponse response, java.lang.Object handler)和getLastModified(HttpServletRequest request, java.lang.Object handler)。

supports方法检验给定的handler是否支持当前HandlerAdapter;

handle方法用于处理程序。此对象必须先前已传递给supports方法supports已返回true。

getLastModified方法与HttpServlet的getLastModified方法相同的一样,返回上次修改请求的时间。如果处理程序类中没有支持,则可以简单地返回-1。

请求进来DispatcherServlet在doDispatch(HttpServletRequest request, HttpServletResponse response)方法中获取适配器:

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
		for (HandlerAdapter ha : this.handlerAdapters) {
			if (logger.isTraceEnabled()) {
				logger.trace("Testing handler adapter [" + ha + "]");
			}
			if (ha.supports(handler)) {
				return ha;
			}
		}
		throw new ServletException("No adapter for handler [" + handler +
				"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
	}

getHandlerAdapter(Object handler)通过遍历已加载的适配器的supports方法,判断使用哪一个适配器。然后用用那个适配器的handle()方法处理应用程序。处理完返回一个ModelAndView对象。

HttpRequestHandlerAdapter

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

HttpRequestHandlerAdapter的supports方法,根据适配器是否实现HttpRequestHandler判断。

public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		((HttpRequestHandler) handler).handleRequest(request, response);
		return null;
	}

直接调用HttpRequestHandler.handleRequest方法,这里不是通过返回数据实现和前端交互,而是直接通过改写HttpServletResponse实现前后端交互

SimpleControllerHandlerAdapter

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

SimpleControllerHandlerAdapter的supports方法,根据适配器是否实现Controller判断。

@Nullable
	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

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

调用Controller.handleRequest方法,Controller的实现类的handleRequest然后返回ModelAndView。

RequestMappingHandlerAdapter

public final boolean supports(Object handler) {
		return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
	}

这是RequestMappingHandlerAdapter沿用父类的supports方法,根据适配器是否实现HandlerMethod及能否转换成HandlerMethod判断。

protected ModelAndView handleInternal(HttpServletRequest request,
			HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

		ModelAndView mav;
		checkRequest(request);

		// 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) {
					mav = invokeHandlerMethod(request, response, handlerMethod);
				}
			}
			else {
				// No HttpSession available -> no mutex necessary
				mav = invokeHandlerMethod(request, response, handlerMethod);
			}
		}
		else {
			// No synchronization on session demanded at all...
			mav = invokeHandlerMethod(request, response, handlerMethod);
		}

		if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
			if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
				applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
			}
			else {
				prepareResponse(response);
			}
		}

		return mav;
	}

RequestMappingHandlerAdapter先调用继承自父类的handle方法,handle调用它自身的handleInternal()方法去处理程序。

mav = invokeHandlerMethod(request, response, handlerMethod);

invokeHandlerMethod方法就是具体去处理应用程序逻辑的方法。

猜你喜欢

转载自blog.csdn.net/qq_26400953/article/details/86642906