SpringMVC源碼情操陶冶-HandlerAdapter適配器簡析


springmvc中對業務的具體處理是通過HandlerAdapter適配器操作的

HandlerAdapter接口方法

列表如下

/**
	 * Given a handler instance, return whether or not this {@code HandlerAdapter}
	 * can support it. Typical HandlerAdapters will base the decision on the handler
	 * type. HandlerAdapters will usually only support one handler type each.
	 * <p>A typical implementation:
	 * <p>{@code
	 * return (handler instanceof MyHandler);
	 * }
	 * @param handler handler object to check
	 * @return whether or not this object can use the given handler
	 */
	boolean supports(Object handler);

	/**
	 * Use the given handler to handle this request.
	 * The workflow that is required may vary widely.
	 * @param request current HTTP request
	 * @param response current HTTP response
	 * @param handler handler to use. This object must have previously been passed
	 * to the {@code supports} method of this interface, which must have
	 * returned {@code true}.
	 * @throws Exception in case of errors
	 * @return ModelAndView object with the name of the view and the required
	 * model data, or {@code null} if the request has been handled directly
	 */
	ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

	/**
	 * Same contract as for HttpServlet's {@code getLastModified} method.
	 * Can simply return -1 if there's no support in the handler class.
	 * @param request current HTTP request
	 * @param handler handler to use
	 * @return the lastModified value for the given handler
	 * @see javax.servlet.http.HttpServlet#getLastModified
	 * @see org.springframework.web.servlet.mvc.LastModified#getLastModified
	 */
	long getLastModified(HttpServletRequest request, Object handler);

下面針對以上接口對springmvc內置的實現類作下簡析

AbstractHandlerMethodAdapter-處理HandlerMethod業務

處理handler類型為HandlerMethod.class的請求,這是常用的請求方式,一般都是返回視圖給前台頁面

	@Override
	public final boolean supports(Object handler) {
		return (handler instanceof HandlerMethod && supportsInternal((HandlerMethod) handler));
	
	@Override
	public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		//供子類實現調用
		return handleInternal(request, response, (HandlerMethod) handler);
	}

	@Override
	public final long getLastModified(HttpServletRequest request, Object handler) {
		//供子類實現調用
		return getLastModifiedInternal(request, (HandlerMethod) handler);
	}

以下看下主要實現類RequestMappingHandlerAdapter的具體實現代碼

RequestMappingHandlerAdapter#supportsInternal()

直接返回true,表明handler為HandlerMethod對象即可

	@Override
	protected boolean supportsInternal(HandlerMethod handlerMethod) {
		return true;
	}

RequestMappingHandlerAdapter#handleInternal()-業務處理邏輯

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

		ModelAndView mav;
		//確定請求是否符合,比如是否為GET/POST請求,可配置
		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 {
			//最終通過invokeHandlerMethod()方法創建ModelAndView視圖對象,這里涉及到反射機制使用
			mav = invokeHandlerMethod(request, response, handlerMethod);
		}
		//設置關於cache的頭部信息
		if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
			if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
				applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
			}
			else {
				prepareResponse(response);
			}
		}

		return mav;
	}

RequestMappingHandlerAdapter的關鍵方法invokeHandlerMethod(),采用的是反射的思想來獲取視圖對象,有興趣的可自行查閱分析

HttpRequestHandlerAdapter-處理HttpRequestHandler接口業務

處理handler類型為HttpRequestHandler.class的請求,簡單的http請求,常用的有靜態資源映射請求ResourceHttpRequestHandler,其包裝在SimpleUrlHandlerMapping中,具體可看>>>SpringMVC源碼情操陶冶-ResourcesBeanDefinitionParser靜態資源解析器

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

	@Override
	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		//調用handleRequest()接口方法直接返回內容給前端
		//ResourceHttpRequestHandler返回請求的靜態資源文件給前端
		((HttpRequestHandler) handler).handleRequest(request, response);
		return null;
	}

	@Override
	public long getLastModified(HttpServletRequest request, Object handler) {
		if (handler instanceof LastModified) {
			return ((LastModified) handler).getLastModified(request);
		}
		return -1L;
	}

SimpleControllerHandlerAdapter-處理Controller接口業務

處理handler類型為Controller.class的請求,一般不采用

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

	@Override
	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		//調用Controller接口類的接口方法handleRequest()方法直接響應給前端
		return ((Controller) handler).handleRequest(request, response);
	}

	@Override
	public long getLastModified(HttpServletRequest request, Object handler) {
		if (handler instanceof LastModified) {
			return ((LastModified) handler).getLastModified(request);
		}
		return -1L;
	}

SimpleServletHandlerAdapter-處理Servlet接口業務

處理handler類型為Servlet.class的請求,一般不采用

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

	@Override
	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		//直接調用Servlet的service接口返回
		((Servlet) handler).service(request, response);
		return null;
	}

	@Override
	public long getLastModified(HttpServletRequest request, Object handler) {
		return -1;
	}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM