spring mvc 源码分析之处理器和适配器的获取

spring mvc 源码分析

流程图

在这里插入图片描述
在这里插入图片描述

一、Handler是什么?

handler在springmvc中代表了控制器,interceptors是拦截器,后面我们通过手写实现spring mvc就能清楚的知道,简单理解其实就是控制类中的某个方法,上面标注了请求路径,与其一一绑定的一个方法来处理请求。

在源码中handler 是一个object类的变量名。用来接收HandlerMethod 类。
HandlerMethod 类中封装了集体需要调用的方法,哪一个控制类 ,方法所需要的参数信息等等。

public class HandlerMethod {

	/** Logger that is available to subclasses. */
	protected final Log logger = LogFactory.getLog(getClass());

// 方法所在实现类
	private final Object bean;

	@Nullable
	private final BeanFactory beanFactory;

	private final Class<?> beanType;
// 方法对象
	private final Method method;

	private final Method bridgedMethod;

// 方法所需要的参数
	private final MethodParameter[] parameters;

	@Nullable
	private HttpStatus responseStatus;

	@Nullable
	private String responseStatusReason;

	@Nullable
	private HandlerMethod resolvedFromHandlerMethod;

// 方法标注的注解集合
	@Nullable
	private volatile List<Annotation[][]> interfaceParameterAnnotations;

	private final String description;

一、如何通过请求路径找到对应的HandlerExecutionChain

HandlerExecutionChain包含 Handler(控制器)和HandlerInterceptor(拦截器)

DispatcherServlet#doDispatch方法中的getHandler(processedRequest)就是来获取HandlerExecutionChain。
在这里插入图片描述
上图的四个handlerMapping是在初始化时就生成好的。
在这里插入图片描述

AbstractHandlerMapping#getHandler(HttpServletRequest request)获取处理器

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 = obtainApplicationContext().getBean(handlerName);
		}

		// 将处理器和拦截器封装成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 (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
			CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(request) : null);
			CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
			config = (config != null ? config.combine(handlerConfig) : handlerConfig);
			executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
		}

		return executionChain;
	}

AbstractHandlerMethodMapping#getHandlerInternal(HttpServletRequest request)

protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
// 获取当前请求的请求路径
		String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
		request.setAttribute(LOOKUP_PATH, lookupPath);
		// 获取读锁
		this.mappingRegistry.acquireReadLock();
		try {
			HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
			return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
		}
		finally {
		// 解锁
			this.mappingRegistry.releaseReadLock();
		}
	}

lookupHandlerMethod(lookupPath, request) 获取到HandlerMethod

protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
		// 里面存放路径和处理方法的映射
		List<Match> matches = new ArrayList<>();
		List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
		if (directPathMatches != null) {
			// 循环去查找并放入匹配集合中
			addMatchingMappings(directPathMatches, matches, request);
		}
		if (matches.isEmpty()) {
			// No choice but to go through all mappings...
			addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
		}

		if (!matches.isEmpty()) {
			Match bestMatch = matches.get(0);
			// 找出两个处理器 会判断请求方式
			if (matches.size() > 1) {
				Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
				matches.sort(comparator);
				bestMatch = matches.get(0);
				if (logger.isTraceEnabled()) {
					logger.trace(matches.size() + " matching mappings: " + matches);
				}
				if (CorsUtils.isPreFlightRequest(request)) {
					return PREFLIGHT_AMBIGUOUS_MATCH;
				}
				Match secondBestMatch = matches.get(1);
				if (comparator.compare(bestMatch, secondBestMatch) == 0) {
					Method m1 = bestMatch.handlerMethod.getMethod();
					Method m2 = secondBestMatch.handlerMethod.getMethod();
					String uri = request.getRequestURI();
					throw new IllegalStateException(
							"Ambiguous handler methods mapped for '" + uri + "': {" + m1 + ", " + m2 + "}");
				}
			}
			request.setAttribute(BEST_MATCHING_HANDLER_ATTRIBUTE, bestMatch.handlerMethod);
			handleMatch(bestMatch.mapping, lookupPath, request);
			return bestMatch.handlerMethod;
		}
		else {
			return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
		}
	}

一、HandlerAdapter

在这里插入图片描述
在这里插入图片描述
源码分析
在这里插入图片描述

一、HandlerAdapter调用handler处理之前

如果有拦截器会先调用拦截器的preHandle方法,返回true才能继续执行。
在这里插入图片描述

DispatcherServlet#mappedHandler.applyPreHandle(processedRequest, response)

	boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
		// 获取配置的拦截器数组
		HandlerInterceptor[] interceptors = getInterceptors();
		if (!ObjectUtils.isEmpty(interceptors)) {
			for (int i = 0; i < interceptors.length; i++) {
				HandlerInterceptor interceptor = interceptors[i];
				// 执行拦截器的preHandle方法 如果该方法返回false就不会进入handler进行数据处理
				if (!interceptor.preHandle(request, response, this.handler)) {
					triggerAfterCompletion(request, response, null);
					return false;
				}
				this.interceptorIndex = i;
			}
		}
		return true;
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

起风了 收衣服

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值