美文网首页
Spring mvc执行流程图-HandlerMapping接口

Spring mvc执行流程图-HandlerMapping接口

作者: engineer_tang | 来源:发表于2020-08-25 07:55 被阅读0次

    再次来回顾下Spring mvc的请求映射流程吧,首先,客户端发送请求被DispathcerServlet拦截,然后把请求作为参数调用handlerMappings找到对应的HandlerMapping得到Handler封装成HandlerExecutionChain对象返回给DispatcherServlet处理器。

    1. HandlerMapping接口

    接口定义如下

    public interface HandlerMapping {
    
        String BEST_MATCHING_HANDLER_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingHandler";
    
    
        String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class.getName() + ".pathWithinHandlerMapping";
    
    
        String BEST_MATCHING_PATTERN_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingPattern";
    
    
        String INTROSPECT_TYPE_LEVEL_MAPPING = HandlerMapping.class.getName() + ".introspectTypeLevelMapping";
    
    
        String URI_TEMPLATE_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".uriTemplateVariables";
    
    
        String MATRIX_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".matrixVariables";
    
        String PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE = HandlerMapping.class.getName() + ".producibleMediaTypes";
    
        @Nullable
        HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
    
    }
    

    从接口定义中可以发现,该接口只有一个抽象方法getHandler,返回参数为一个HandlerExecutionChain对象。


    image.png

    MatchableHandlerMapping接口通过继承HandlerMapping接口,增加了新的match抽象方法,

        @Nullable
        RequestMatchResult match(HttpServletRequest request, String pattern);
    

    该方法作用是在确定给定的请求是否符合请求条件

    2 Handler映射执行流程

    image.png

    获取到Handler对象后封装成HandlerExecutionChain对象的核心代码:

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

    3. 自定义拦截器

    实现拦截器的步骤:

    1. 实现HandlerInterceptor 接口
    2. 注册到Spring容器中

    3.1 实现方案

    HandlerInterceptor的接口定义如下:

    public interface HandlerInterceptor {
    
        default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
    
            return true;
        }
    
        default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                @Nullable ModelAndView modelAndView) throws Exception {
        }
    
        default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                @Nullable Exception ex) throws Exception {
        }
    }
    

    自定义拦截器必须实现该接口,下面自定义拦截器代码:

    public class TestHandlerInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
        }
    }
    

    实现Springboot 自动配置拦截器

    package com.joe.code.common.configuration;
    
    import com.joe.code.common.component.TestResolver;
    import com.joe.code.common.intercepter.TestHandlerInterceptor;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.method.support.HandlerMethodArgumentResolver;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    import java.util.List;
    
    // 注册resolver
    @Configuration
    public class WebConfiguration implements WebMvcConfigurer {
    
        @Autowired
        private ApplicationContext context;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new TestHandlerInterceptor());
        }
    }
    
    

    相关文章

      网友评论

          本文标题:Spring mvc执行流程图-HandlerMapping接口

          本文链接:https://www.haomeiwen.com/subject/bghajktx.html