从DispatcherServlet到HandlerAdapter

本文深入探讨了Tomcat启动过程中DispatcherServlet初始化HandlerAdapter的机制,详细解析了默认加载的处理适配器,包括HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter和RequestMappingHandlerAdapter的工作原理。同时,介绍了HandlerAdapter中supports、handle和getLastModified方法的功能及其在处理HTTP请求中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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方法就是具体去处理应用程序逻辑的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

游语

对你有帮助,可以请我喝杯奶哦

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值