spring 源碼分析 管理請求映射-下 (RequestMappingHandlerMapping)

RequestMappingHandlerMapping 類是 HandlerMapping接口 的實現, 是spring 定義的默認處理流程

  • spring mvc 請求流程:
    ---- 其中需要通過HttpRequestServlet 請求對象獲取HandlerExecutionChain 對象
    ---- HandlerExecutionChain 對象包含 HandlerMethod 與 HandlerInterceptor攔截器
    在這裏插入圖片描述

直接源碼分析:

	/**
	 * 返回此請求的HandlerExecutionChain
	 * <p>按順序嘗試所有處理程序映射
	 */
	@Nullable
	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		if (this.handlerMappings != null) {
			for (HandlerMapping mapping : this.handlerMappings) {
				HandlerExecutionChain handler = mapping.getHandler(request);
				if (handler != null) {
					return handler;
				}
			}
		}
		return null;
	}

遍歷所有HandlerMapping 的實現類, 通過getHandler() 方法獲取HandlerExecutionChain 對象

org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandler()

/**
	 * 通過Request請求獲取 HandlerExecutionChain
	 * 		1、通過請求路徑獲取 HandlerMethod ==>> getHandlerInternal(request)
	 * 		2、通過HandlerMethod 與 HandlerInterceptor 創建 HandlerExecutionChain
	 * 		3、跨域cors    (暫不分析)
	 */
	@Override
	@Nullable
	public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		// 抽象方法, 子類實現.  創建 HandlerMethod
		Object handler = getHandlerInternal(request);
		if (handler == null) {
			handler = getDefaultHandler();
		}
		if (handler == null) {
			return null;
		}
		// Bean name or resolved handler?
		if (handler instanceof String) {
			String handlerName = (String) handler;
			handler = obtainApplicationContext().getBean(handlerName);
		}

		// 通過 HandlerMethod, Request 獲取 HandlerExecutionChain
		HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

		if (logger.isTraceEnabled()) {
			logger.trace("Mapped to " + handler);
		}
		else if (logger.isDebugEnabled() && !request.getDispatcherType().equals(DispatcherType.ASYNC)) {
			logger.debug("Mapped to " + executionChain.getHandler());
		}

		if (CorsUtils.isCorsRequest(request)) {
			CorsConfiguration globalConfig = this.corsConfigurationSource.getCorsConfiguration(request);
			CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
			CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
			executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
		}

		return executionChain;
	}

	/**
	 * 獲取 HandlerExecutionChain 對象
	 * 		1、通過 HandlerMethod, 創建 HandlerExecutionChain
	 * 		2、遍歷所有攔截器, 將非MappedInterceptor 攔截器添加到 HandlerExecutionChain 中
	 */
	protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
		//通過 HandlerMethod 創建 HandlerExecutionChain
		HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));

		// 通過 UrlPathHelper 對象來獲取請求的路徑  
		//@see org.springframework.web.util.UrlPathHelper#getLookupPathForRequest(HttpServletRequest)
		String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
		for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
			if (interceptor instanceof MappedInterceptor) {
				MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
				if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
					chain.addInterceptor(mappedInterceptor.getInterceptor());
				}
			}
			else {
				chain.addInterceptor(interceptor);
			}
		}
		return chain;
	}

類介紹:

HandlerMethod:對@RequestMapping標記請求方法的封裝, Method, Bean, MethodParameter 封裝
HandlerExecutionChain: 對攔截器HandlerInterceptor 與 HandlerMethod 的封裝。
HandlerMapping: 接口 主要用於處理映射請求路徑
HandlerInterceptor: spring 攔截器, 前置處理preHandle, 後置處理postHandle

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章