前言
当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当中去```javapublic 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。 这样咱们就能够应用这些拦截器了。
总结
最初以一个流程图直观总结一下其过程: