AbstractDetectingUrlHandlerMapping類中的initApplicationContext()方法有一條線是注冊處理器铅乡,另一條線是初始化攔截器分瘦。在SpringMVC之HandlerMapping中我們走讀了注冊處理器的過程,接下來我們看一下攔截器的初始化這條線。
配置攔截器
//在dispatcher-servlet.xml文件中添加下面代碼:
//DefaultInterceptor實現(xiàn)HandlerInterceptor乘凸,<mvc:interceptors>配置的時候茉稠,直接MappedInterceptor。
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="interceptor.DefaultInterceptor">
</mvc:interceptor>
</mvc:interceptors>
//WebInterceptor實現(xiàn)HandlerInterceptor卿吐,<bean <property>>配置的時候旁舰,判斷后添加到adaptedInterceptors。
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
<property name="interceptors">
<list>
<bean class="interceptor.DefaultInterceptor1" />
</list>
</property>
</bean>
備注: 上面配置文件中兩種攔截器配置方式會產(chǎn)生兩個不同的BeanNameUrlHandlerMapping實例嗡官,那個攔截器配置在前那個BeanNameUrlHandlerMapping實例執(zhí)行箭窜;這樣的話,后面配置的攔截器將不會被執(zhí)行衍腥,所以在配置攔截器的時候選取一種方式即可磺樱。
重要接口和類
HandlerExecutionChain
Handler和Interceptor集合組成的類HandlerInterceptor
SpringMVC攔截器基礎(chǔ)接口AbstractHandlerMapping
HandlerMapping的基礎(chǔ)抽象類AsyncHandlerInterceptor
繼承HandlerInterceptor的接口,額外提供了afterConcurrentHandlingStarted方法婆咸,該方法是用來處理異步請求坊罢。當(dāng)Controller中有異步請求方法的時候會觸發(fā)該方法。異步請求先支持preHandle擅耽、然后執(zhí)行afterConcurrentHandlingStarted活孩。異步線程完成之后執(zhí)行preHandle、postHandle乖仇、afterCompletion憾儒。
HandlerInterceptorAdapter
實現(xiàn)AsyncHandlerInterceptor接口的抽象類WebRequestInterceptor
與HandlerInterceptor接口類似,區(qū)別是WebRequestInterceptor的preHandle沒有返回值乃沙。還有WebRequestInterceptor是針對請求的起趾,接口方法參數(shù)中沒有response。
- MappedInterceptor
一個包括includePatterns和excludePatterns字符串集合并帶有HandlerInterceptor的類警儒。 很明顯训裆,就是對于某些地址做特殊包括和排除的攔截器眶根。
- ConversionServiceExposingInterceptor
默認(rèn)的<annotation-driven/>標(biāo)簽初始化的時候會初始化ConversionServiceExposingInterceptor這個攔截器,并被當(dāng)做構(gòu)造方法的參數(shù)來構(gòu)造MappedInterceptor边琉。之后會被加入到AbstractHandlerMapping的mappedInterceptors集合中属百。該攔截器會在每個請求之前往request中丟入ConversionService。主要用于spring:eval標(biāo)簽的使用变姨。
源碼走讀
//AbstractDetectingUrlHandlerMapping類中initApplicationContext()實現(xiàn)
public void initApplicationContext() throws ApplicationContextException {
//初始化攔截器
super.initApplicationContext();
detectHandlers();
}
//AbstractHandlerMapping類中initApplicationContext()實現(xiàn)
protected void initApplicationContext() throws BeansException {
//<bean <property>>配置的攔截器如:DefaultInterceptor1
extendInterceptors(this.interceptors);
//<mvc:interceptors>配置的攔截器如:DefaultInterceptor
detectMappedInterceptors(this.mappedInterceptors);
//將<bean <property>>配置的攔截器添加到對應(yīng)的攔截器List中
initInterceptors();
}
AbstractHandlerMapping類中initInterceptors()實現(xiàn)
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));
}
}
}
}