推荐博客

给大家推荐个靠谱的公众号程序员探索之路,大家一起加油
SpringMVC(七)-----HandlerMapping

引言

主要介绍一下HandlerMapping的作用以及继承关系,之前也介绍过DispatcherServlet会进行HandlerMapping的初始化,之后会详细的介绍每一种源码

上一篇

SpringMVC(六)-----拦截器调用时机
https://blog.csdn.net/yueloveme/article/details/89843985

HandlerMapping

HandlerMapping的作用就是为每个请求找到合适的处理器Handler,简单的理解就是维护了一个url到Controller关系的map结构,在代码层面看到的结果就是请求获得执行链(HandlerExecutionChain),接口中只有一个方法获取执行链

/**
	 * Return a handler and any interceptors for this request. The choice may be made
	 * on request URL, session state, or any factor the implementing class chooses.
	 * <p>The returned HandlerExecutionChain contains a handler Object, rather than
	 * even a tag interface, so that handlers are not constrained in any way.
	 * For example, a HandlerAdapter could be written to allow another framework's
	 * handler objects to be used.
	 * <p>Returns {@code null} if no match was found. This is not an error.
	 * The DispatcherServlet will query all registered HandlerMapping beans to find
	 * a match, and only decide there is an error if none can find a handler.
	 * @param request current HTTP request
	 * @return a HandlerExecutionChain instance containing handler object and
	 * any interceptors, or {@code null} if no mapping found
	 * @throws Exception if there is an internal error
	 */
	HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;

类关系图

SpringMVC(七)-----HandlerMapping

AbstractHandlerMapping

/**
	 * Look up a handler for the given request, falling back to the default
	 * handler if no specific one is found.
	 * @param request current HTTP request
	 * @return the corresponding handler instance, or the default handler
	 * @see #getHandlerInternal
	 */
	 实现getHandler方法
	@Override
	public final HandlerExecutionChain getHandler(HttpServletRequest request) throws 
	Exception {
		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 = getApplicationContext().getBean(handlerName);
		}

		HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, 
		request);
		if (CorsUtils.isCorsRequest(request)) {
			CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request);
			CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
			CorsConfiguration config = (globalConfig != null ? 
			globalConfig.combine(handlerConfig) : handlerConfig);
			executionChain = getCorsHandlerExecutionChain(request, executionChain, 
			config);
		}
		return executionChain;
	}
	/**
	 * Build a {@link HandlerExecutionChain} for the given handler, including
	 * applicable interceptors.
	 * <p>The default implementation builds a standard {@link HandlerExecutionChain}
	 * with the given handler, the handler mapping's common interceptors, and any
	 * {@link MappedInterceptor}s matching to the current request URL. Interceptors
	 * are added in the order they were registered. Subclasses may override this
	 * in order to extend/rearrange the list of interceptors.
	 * <p><b>NOTE:</b> The passed-in handler object may be a raw handler or a
	 * pre-built {@link HandlerExecutionChain}. This method should handle those
	 * two cases explicitly, either building a new {@link HandlerExecutionChain}
	 * or extending the existing chain.
	 * <p>For simply adding an interceptor in a custom subclass, consider calling
	 * {@code super.getHandlerExecutionChain(handler, request)} and invoking
	 * {@link HandlerExecutionChain#addInterceptor} on the returned chain object.
	 * @param handler the resolved handler instance (never {@code null})
	 * @param request current HTTP request
	 * @return the HandlerExecutionChain (never {@code null})
	 * @see #getAdaptedInterceptors()
	 */
	protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
		HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
				(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));

		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;
	}

从handlermapping的类关系图中可以看到AbstractHandlerMapping有两个实现类

AbstractUrlHandlerMapping

通过url来进行匹配,将url和对应的handler保存在一个map中

AbstractHandlerMethodMapping

将具体的method作为handler来使用,比如经常使用的@RequestMapping所注释的方法就是这种handler,这种handler是HandlerMethod

相关文章:

  • 2022-12-23
  • 2021-06-18
  • 2021-10-10
  • 2021-08-19
  • 2021-05-03
  • 2021-08-03
  • 2022-12-23
  • 2021-06-08
猜你喜欢
  • 2021-09-10
  • 2022-12-23
  • 2022-12-23
  • 2018-04-03
  • 2021-09-26
  • 2021-09-07
  • 2022-12-23
相关资源
相似解决方案