SpringMVC------AbstractHandlerMapping

本文深入探讨了SpringMVC框架中Handler的获取过程及处理链HandlerExecutionChain的创建机制,同时解析了拦截器(Interceptor)的配置与工作原理。

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

初始化

	@Override
	protected void initApplicationContext() throws BeansException {
        //供子类扩展添加拦截器,目前spring没有自行实现
		extendInterceptors(this.interceptors);
        //搜寻springmvc中的MappedInterceptors保存至adaptedInterceptors集合
		detectMappedInterceptors(this.adaptedInterceptors);
        //将interceptors集合添加至adaptedInterceptors集合中
		initInterceptors();
	}

主要目的是获取springmvc上下文中的拦截器集合,此处特指MappedInterceptor。

获取处理链对象

@Override
	@Nullable
	public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        //getHandlerInternal(request)方法为抽象方法,供子类实现
        //获取到的handler对象一般为bean/HandlerMethod
		Object handler = getHandlerInternal(request);
         //上述找不到则使用默认的处理类,没有设定则返回null,则会返回前台404错误
		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 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());
		}
        //针对cros跨域请求的处理
		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;
	}

由以上代码分析可知,需要观察下如何获取handler对象以及创建HandlerExecutionChain处理链对象

getHandlerInternal()

针对HandlerMethod的获取

	@Override
	protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
        //获取访问的路径,一般类似于request.getServletPath()返回不含contextPath的访问路径
		String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
        //获取读锁
		this.mappingRegistry.acquireReadLock();
		try {
            //获取HandlerMethod作为handler对象,这里涉及到路径匹配的优先级
            //优先级:精确匹配>最长路径匹配>扩展名匹配
    		HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
            //HandlerMethod内部含有bean对象,其实指的是对应的Controller
			return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
		}
		finally {
            //释放读锁
			this.mappingRegistry.releaseReadLock();
		}
	}

针对beanName的获取

@Override
	@Nullable
	protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
		String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
        //从handlerMap查找路径对应的beanName
		Object handler = lookupHandler(lookupPath, request);
		if (handler == null) {
			// We need to care for the default handler directly, since we need to
			// expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
			Object rawHandler = null;
			if ("/".equals(lookupPath)) {
				rawHandler = getRootHandler();
			}
			if (rawHandler == null) {
				rawHandler = getDefaultHandler();
			}
			if (rawHandler != null) {
				// Bean name or resolved handler?
				if (rawHandler instanceof String) {
					String handlerName = (String) rawHandler;
					rawHandler = obtainApplicationContext().getBean(handlerName);
				}
				validateHandler(rawHandler, request);
				handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
			}
		}
		return handler;
	}

getHandlerExecutionChain()-创建处理链对象

HandlerExecutionChain的内部属性

        //真实处理请求对象
    private final Object handler;
        
        //拦截器集合
    private HandlerInterceptor[] interceptors;
        
        //拦截器集合
    private List<HandlerInterceptor> interceptorList;
        
        //拦截器开始下标,默认正序执行
    private int interceptorIndex = -1;
//此处的handler可为HandlerMethod/beanName
    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;
    }

处理链的创建基本就是 带有handler对象以及添加拦截器对象集合,用于后期的拦截。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值