SpringMVC配置静态资源引起对拦截器的源码学习

(一) 拦截器配置

对于Web应用而言,URL就表示资源,URL就表示一个操作,Spring MVC也正是对URL的匹配进行相关操作,但是有些时候WEBUI的js、图片以及HTML等静态资源对应的URL不是一种操作,而仅仅是显示的资源给用户提供操作的界面。因此我们就需要对这些静态资源进行不拦截处理,同时还需要对一些登陆页面的URL不拦截,因此一般需要进行如下类似配置:

<mvc:interceptors>
     <mvc:interceptor>
        // 具体配置省略
     </mvc:interceptor>
     <mvc:interceptor>
      // 具体配置省略
      </mvc:interceptor>
</mvc:interceptors>

SpringMVC配置静态资源引起对拦截器的源码学习

有些时候需要将静态资源的URL与请求URL做映射,主要可以Java代码或者XML方式,分别如下:

@Bean
public WebMvcConfigurer configurer() {
    return new WebMvcConfigurer() {
        @Override
 public void addResourceHandlers(ResourceHandlerRegistry registry) {
            registry.addResourceHandler("/daxin/**").addResourceLocations("classpath:/dist/views/"); //将daxin后面**内容追加到locations后面返回资源
 registry.addResourceHandler("/static/**").addResourceLocations("classpath:/dist/static/");
 registry.addResourceHandler("/_m/**").addResourceLocations("classpath:/dist/_m/");
 }
    };
}

或者XML:

<mvc:resources mapping="/js/**" location="/static_resources/javascript/"/> 

到此处就完成了静态资源的配置,由于之前看过拦截器的处理源码,主要是在DispatchServlet中进行的处理,但是本次由于配置的拦截器有拦截URL与不拦截URL,引起了对拦截器如何针对不同URL的拦截处理的细节感兴趣了。(之前是认为所有的拦截器都是固定的,从头到尾对请求进行前后置处理)。接下来就看下如何拦截的。首先介绍两个类的基本职责有助于理解拦截器处理过程,分别如下:

1:Spring mvc中HandlerMethod是一个Controller的方法封装,表示一个处理请求的方法!

SpringMVC配置静态资源引起对拦截器的源码学习

2:HandlerExecutionChain是HandlerMethod与拦截器的封装类,一次请求就可以由该类处理,先调用处理器进行前置处理,然后处理请求,最后拦截器后置处理等。

SpringMVC配置静态资源引起对拦截器的源码学习

将上面两个类职责了解清楚接下来就看拦截器内容了。

(二)拦截器的加载以及如何生效!

mvc:intercepter相关源码:

1: org.springframework.web.servlet.config.InterceptorsBeanDefinitionParser: 负责解析XML中的拦截器!解析之后设置到org.springframework.web.servlet.handler.MappedInterceptor的成员中。

 

2: 在org.springframework.web.servlet.handler.AbstractHandlerMapping#getHandlerExecutionChain方法中判断URL是否拦截,如果拦截的话就将对应拦截器放到拦截链中。有关是否拦截URL的校验在org.springframework.web.servlet.handler.MappedInterceptor#matches方法负责是否拦截处理。

SpringMVC配置静态资源引起对拦截器的源码学习

 

org.springframework.web.servlet.DispatcherServlet中进行拦截器处理的代码:

SpringMVC配置静态资源引起对拦截器的源码学习

结论就是:在DispatchServlet中拦截器处理时,不同的请求URL对应着不同的拦截器数组,每一个拦截器数组都是根据实际的请求URL进行得到拦截器数组的!