乐趣区

关于spring:springmvc详解3请求分发流程之拦截器-HandlerInterceptor

前言

当 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。这样咱们就能够应用这些拦截器了。

总结

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

退出移动版