美文网首页JAVA学习文集
springmvc详解(3)请求分发流程之拦截器 Handler

springmvc详解(3)请求分发流程之拦截器 Handler

作者: 小燃儿 | 来源:发表于2020-11-07 16:04 被阅读0次

    前言

    当Servlet接收到请求后会最终调用doDispatch方法后会去找到对应的HandlerMapping,同时也会找到配置的拦截器,最终组成需要的HandlerExecutionChain执行链(这里省略部分代码保留主要功能):

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    
                    // 1.确定使用的handler
                    HandlerExecutionChain mappedHandler = getHandler(processedRequest);
                    if (mappedHandler == null) {
                        noHandlerFound(processedRequest, response);
                        return;
                    }
    
                    // 确定handler的适配器
                    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    
                    // 拦截器前置调用
                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }
    
                    // 实际调用
                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                    // 设置默认视图名
                    applyDefaultViewName(processedRequest, mv);
                    // 拦截器后置调用
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                // 分发结果
                processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
        }
    

    拦截器

    在开发中拦截器的使用是比较频繁的,例如用户拦截器,权限拦截器等。sringmvc的拦截器提供了pre,post,after三种时期的方法(调用处理器方法前,调用后,返回数据后),非常方便的进行资源设置,释放等功能。

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

    拦截器注册

    现在看看拦截器是怎么注册的?spring提供两种方式。
    1. 配置类注册EnableWebMvcConfiguration#setConfigurers
    通常在开发中我们会使用自己编写实现WebMvcConfigurer接口的方式添加拦截器,并把注册类注册到IOC容器中,EnableWebMvcConfiguration#setConfigurers就会使用@Autowired进行制动注入。
    java @Autowired(required = false) public void setConfigurers(List<WebMvcConfigurer> configurers) { if (!CollectionUtils.isEmpty(configurers)) { this.configurers.addWebMvcConfigurers(configurers); } }
    最后把注册的拦截器注册到HandlerMapping当中去,(以RequestMappingHandlerMapping为例)代码如下,getInterceptors方法最终会调用所有WebMvcConfigurer实例添加拦截器的方法,从而将我们自定义的拦截器注册到HanderMapping当中去
    ```java
    public RequestMappingHandlerMapping requestMappingHandlerMapping(
    @Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
    @Qualifier("mvcConversionService") FormattingConversionService conversionService,
    @Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {

            RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
            mapping.setOrder(0);
            mapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));
            ……
    ```
    2. 以MappedInterceptor类实例或者子类直接注册到IOC容器中
    由于HandlerMapping继承WebApplicationObjectSupport,再创建bean的时候会调用其initApplicationContext方法。而该方法会注册容器中的MappedInterceptor类的bean。
        这样我们就可以使用这些拦截器了。
    

    总结

    最后以一个流程图直观总结一下其过程:


    image.png

    相关文章

      网友评论

        本文标题:springmvc详解(3)请求分发流程之拦截器 Handler

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