AbstractDetectingUrlHandlerMapping类中的initApplicationContext()方法有一条线是注册处理器,另一条线是初始化拦截器。在SpringMVC之HandlerMapping中我们走读了注册处理器的过程,接下来我们看一下拦截器的初始化这条线。
配置拦截器
//在dispatcher-servlet.xml文件中添加下面代码:
//DefaultInterceptor实现HandlerInterceptor,<mvc:interceptors>配置的时候,直接MappedInterceptor。
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="interceptor.DefaultInterceptor">
</mvc:interceptor>
</mvc:interceptors>
//WebInterceptor实现HandlerInterceptor,<bean <property>>配置的时候,判断后添加到adaptedInterceptors。
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors">
<list>
<bean class="interceptor.DefaultInterceptor1" />
</list>
</property>
</bean>
备注: 上面配置文件中两种拦截器配置方式会产生两个不同的BeanNameUrlHandlerMapping实例,那个拦截器配置在前那个BeanNameUrlHandlerMapping实例执行;这样的话,后面配置的拦截器将不会被执行,所以在配置拦截器的时候选取一种方式即可。
重要接口和类
HandlerExecutionChain
Handler和Interceptor集合组成的类HandlerInterceptor
SpringMVC拦截器基础接口AbstractHandlerMapping
HandlerMapping的基础抽象类AsyncHandlerInterceptor
继承HandlerInterceptor的接口,额外提供了afterConcurrentHandlingStarted方法,该方法是用来处理异步请求。当Controller中有异步请求方法的时候会触发该方法。异步请求先支持preHandle、然后执行afterConcurrentHandlingStarted。异步线程完成之后执行preHandle、postHandle、afterCompletion。
HandlerInterceptorAdapter
实现AsyncHandlerInterceptor接口的抽象类WebRequestInterceptor
与HandlerInterceptor接口类似,区别是WebRequestInterceptor的preHandle没有返回值。还有WebRequestInterceptor是针对请求的,接口方法参数中没有response。
- MappedInterceptor
一个包括includePatterns和excludePatterns字符串集合并带有HandlerInterceptor的类。 很明显,就是对于某些地址做特殊包括和排除的拦截器。
- ConversionServiceExposingInterceptor
默认的<annotation-driven/>标签初始化的时候会初始化ConversionServiceExposingInterceptor这个拦截器,并被当做构造方法的参数来构造MappedInterceptor。之后会被加入到AbstractHandlerMapping的mappedInterceptors集合中。该拦截器会在每个请求之前往request中丢入ConversionService。主要用于spring:eval标签的使用。
源码走读
//AbstractDetectingUrlHandlerMapping类中initApplicationContext()实现
public void initApplicationContext() throws ApplicationContextException {
//初始化拦截器
super.initApplicationContext();
detectHandlers();
}
//AbstractHandlerMapping类中initApplicationContext()实现
protected void initApplicationContext() throws BeansException {
//<bean <property>>配置的拦截器如:DefaultInterceptor1
extendInterceptors(this.interceptors);
//<mvc:interceptors>配置的拦截器如:DefaultInterceptor
detectMappedInterceptors(this.mappedInterceptors);
//将<bean <property>>配置的拦截器添加到对应的拦截器List中
initInterceptors();
}
AbstractHandlerMapping类中initInterceptors()实现
protected void initInterceptors() {
if (!this.interceptors.isEmpty()) {
for (int i = 0; i < this.interceptors.size(); i++) {
Object interceptor = this.interceptors.get(i);
if (interceptor == null) {
throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null");
}
//List<MappedInterceptor>
if (interceptor instanceof MappedInterceptor) {
this.mappedInterceptors.add((MappedInterceptor) interceptor);
}
//添加到List<HandlerInterceptor>
else {
this.adaptedInterceptors.add(adaptInterceptor(interceptor));
}
}
}
}