RouterFunctionHandlerMapping运行原理

org.springframework.web.servlet.DispatcherServlet.doDispatch{
    // 根据请求对象获取能处理这个请求的Handler,可能是一个HandlerMethod对象,也可能是一个Handler类,它实现了Controller接口等等
   HandlerExecutionChain mappedHandler = getHandler(processedRequest);{
        if (this.handlerMappings != null) {
            // 遍历我们初始化的HandlerMapping,如果不自定义,默认就是提供了三个
            for (HandlerMapping mapping : this.handlerMappings) {
                HandlerExecutionChain handler = mapping.getHandler(request);{
                    // 返回Object是因为getHandlerInternal是一个抽象方法
                    // 处理请求的Handler可能是一个beanName->Bean,也可能是一个实现了Controller接口的对象,等等
                    Object handler = getHandlerInternal(request);{
                        if (this.routerFunction != null) {
                            // 创建ServerRequest对象,这个对象是spring提供的
                            ServerRequest request = ServerRequest.create(servletRequest, this.messageConverters);{
                               return new DefaultServerRequest(servletRequest, messageReaders);{
                                this.serverHttpRequest = new ServletServerHttpRequest(servletRequest);
                                    // 消息处理器
                                    this.messageConverters = Collections.unmodifiableList(new ArrayList<>(messageConverters));
                                    // 请求头
                                    this.headers = new DefaultRequestHeaders(this.serverHttpRequest.getHeaders());
                                    // 请求参数
                                    this.params = CollectionUtils.toMultiValueMap(new ServletParametersMap(servletRequest));
                                    // request中保存的数据
                                    this.attributes = new ServletAttributesMap(servletRequest);
                                    // 请求的路径封装信息
                                    this.requestPath = (ServletRequestPathUtils.hasParsedRequestPath(servletRequest) ?
                                            ServletRequestPathUtils.getParsedRequestPath(servletRequest) :
                                            ServletRequestPathUtils.parseAndCache(servletRequest));
                               }
                            }
                            setAttributes(servletRequest, request);{
                                // public static final String MATCHING_PATTERN_ATTRIBUTE = RouterFunctions.class.getName() + ".matchingPattern";
                                servletRequest.removeAttribute(RouterFunctions.MATCHING_PATTERN_ATTRIBUTE);
                                // 保存Spring创建的请求对象到请求域中
                                servletRequest.setAttribute(RouterFunctions.REQUEST_ATTRIBUTE, request);
                            }
                            return this.routerFunction.route(request){
                                Optional<? extends HandlerFunction<?>> firstRoute = this.first.route(request);
                                // 如果router只存在一个,那么firstRoute就不为空
                                // 否则在存入的时候是套娃的,下面这种格式,所以值就存在second中
                                // (first(first,(first,second),second),second);
                                if (firstRoute.isPresent()) {
                                    // 返回在router中设置的处理类HandlerFunction
                                    return (Optional<HandlerFunction<ServerResponse>>) firstRoute;
                                }
                                // 存入的时候是套娃的
                                Optional<? extends HandlerFunction<?>> secondRoute = this.second.route(request);
                                // 返回在router中设置的处理类HandlerFunction
                                // 这个HandlerFunction是在创建RouterFunction的时候设置进去的
                                return (Optional<HandlerFunction<ServerResponse>>) secondRoute;
                            }.orElse(null);
                        }
                    }
                    // 找了很多资料,没有找到可能成立的情况,可能是兼容老版本的配置,因为上面的Handler都会判断如果为string就从spring容器获取
                    if (handler instanceof String) {
                        String handlerName = (String) handler;
                        handler = obtainApplicationContext().getBean(handlerName);
                    }
                    // 将handler以及拦截器封装成一个HandlerExecutionChain对象
                    HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);{
                        HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
                        for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
                            // 如果是MappedInterceptor这种蓝接触器
                            if (interceptor instanceof MappedInterceptor) {
                                MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
                                // 判断这个拦截器是否可以作用当前请求
                                if (mappedInterceptor.matches(request)) {
                                    // 添加进去拦截器
                                    chain.addInterceptor(mappedInterceptor.getInterceptor());
                                    return;
                                }
                            }
                           chain.addInterceptor(interceptor);
                        }
                        return chain;
                    }
                    // 是否有跨域配置
                    if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
                        CorsConfiguration config = getCorsConfiguration(handler, request);
                        config.validateAllowCredentials();
                        // 添加一个跨域拦截器
                        executionChain = getCorsHandlerExecutionChain(request, executionChain, config);{
                            chain.addInterceptor(0, new CorsInterceptor(config));
                        }
                    }
                    return executionChain;
                }
                // 返回handler
                if (handler != null) {
                    return handler;
                }
            }
        }
   }
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值