Spring 系列 Spring MVC

Posted by lichao modified on March 10, 2020

AOP实现的动态代理中的包括 方法拦截器数组,DispatcherServlet包括的是处理器拦截器。

DispatcherServlet 初始化时调用 onRefresh 方法,调用 initStrategies() 的this.initHandlerMappings(context); 方法中加载拦截器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    protected void onRefresh(ApplicationContext context) {
        this.initStrategies(context);
    }
    protected void initStrategies(ApplicationContext context) {
        this.initMultipartResolver(context);
        this.initLocaleResolver(context);
        this.initThemeResolver(context);
        this.initHandlerMappings(context);
        this.initHandlerAdapters(context);
        this.initHandlerExceptionResolvers(context);
        this.initRequestToViewNameTranslator(context);
        this.initViewResolvers(context);
        this.initFlashMapManager(context);
    }

initHandlerMappings() 方法会加载所有实现 HandlerMappin 的类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
      private void initHandlerMappings(ApplicationContext context) {
        this.handlerMappings = null;
        if (this.detectAllHandlerMappings) {
            Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
            if (!matchingBeans.isEmpty()) {
                this.handlerMappings = new ArrayList(matchingBeans.values());
                AnnotationAwareOrderComparator.sort(this.handlerMappings);
            }
        } else {
            try {
                HandlerMapping hm = (HandlerMapping)context.getBean("handlerMapping", HandlerMapping.class);
                this.handlerMappings = Collections.singletonList(hm);
            } catch (NoSuchBeanDefinitionException var3) {
                ;
            }
        }

在doDispatch方法中,mappedHandler = this.getHandler(processedRequest); 实际是调用抽象类AbstractHandlerMapping 的public final HandlerExecutionChain getHandler(HttpServletRequest request)方法,获取了一个HandlerExecutionChain对象,把匹配request的url的拦截器都加入HandlerExecutionChain。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
        HandlerExecutionChain chain = handler instanceof HandlerExecutionChain ? (HandlerExecutionChain)handler : new HandlerExecutionChain(handler);
        String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
        Iterator var5 = this.adaptedInterceptors.iterator();

        while(var5.hasNext()) {
            HandlerInterceptor interceptor = (HandlerInterceptor)var5.next();
            if (interceptor instanceof MappedInterceptor) {
                MappedInterceptor mappedInterceptor = (MappedInterceptor)interceptor;
                if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
                    chain.addInterceptor(mappedInterceptor.getInterceptor());
                }
            } else {
                chain.addInterceptor(interceptor);
            }
        }
拦截器执行

拦截器的 preHandle 方法是在 HandlerExecutionChain 对象的 applyPreHandle方法中被调用,这个调用是在 HandlerAdapter 对象的 handle 方法也就是 contrller 本身的方法调用之前。postHandle 在之后,最后在 processDispatchResult 处理返回结果和抓异常时执行拦截器的 afterCompletion 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HandlerInterceptor[] interceptors = this.getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) {
                HandlerInterceptor interceptor = interceptors[i];
                if (!interceptor.preHandle(request, response, this.handler)) {
                    this.triggerAfterCompletion(request, response, (Exception)null);
                    return false;
                }
            }
        }

        return true;
    }