返回介绍

2.2 请求分发

发布于 2025-10-03 18:08:54 字数 2818 浏览 0 评论 0 收藏

DispatcherServlet.doDispatch 简略版源码:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) {
    HandlerExecutionChain mappedHandler = getHandler(processedRequest);
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    applyDefaultViewName(processedRequest, mv);
    mappedHandler.applyPostHandle(processedRequest, response, mv);
    processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}

处理器查找

即为请求寻找合适的 Controller 的过程。DispatcherServlet.getHandler:

protected HandlerExecutionChain getHandler(HttpServletRequest request) {
    for (HandlerMapping hm : this.handlerMappings) {
        HandlerExecutionChain handler = hm.getHandler(request);
        if (handler != null) {
            return handler;
        }
    }
    return null;
}

从这里可以看出,寻找处理器实际上委托给 HandlerMapping 实现,寻找的过程便是遍历所有的 HandlerMapping 进行查找, 一旦找到,那么不再继续进行遍历 。也就是说 HandlerMapping 之间有优先级的概念,而根据 AnnotationDrivenBeanDefinitionParser 的注释,RequestMappingHandlerMapping 其实有最高的优先级。

AbstractHandlerMapping.getHandler:

@Override
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
    Object handler = getHandlerInternal(request);
    HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
    //判断请求头中是否有 ORIGIN 字段
    if (CorsUtils.isCorsRequest(request)) {
        CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);
        CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
        CorsConfiguration config = (globalConfig != null ? 
            globalConfig.combine(handlerConfig) : handlerConfig);
        executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
    }
    return executionChain;
}

getHandlerInternal 方法便是根据 url 进行查找的过程,可以参见 MVC 初始化-HandlerMapping 初始化一节。下面重点是执行链的生成。

getHandlerExecutionChain 方法的原理就是从 adaptedInterceptors 中获得所有可以适配当前请求 URL 的 MappedInterceptor 并将其添加到 HandlerExecutionChain 的拦截器列表中。拦截器的顺序其实就是我们定义/注册的顺序。

从 getCorsHandlerExecutionChain 的源码中可以看出,对于跨域请求其实是向调用链插入了一个 CorsInterceptor。

适配器查找

DispatcherServlet.getHandlerAdapter:

protected HandlerAdapter getHandlerAdapter(Object handler) {
    for (HandlerAdapter ha : this.handlerAdapters) {
        if (ha.supports(handler)) {
            return ha;
        }
    }
}

从前面配置解析-注解驱动可以看出,第一个适配器是 RequestMappingHandlerAdapter,而其 support 方法直接返回 true,这就导致了使用的适配器总是这一个。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。