1. 目录

[TOC]

2. 说明

前面springmvc启动流程已经分析到了拦截器是使用InterceptorsBeanDefinitionParser解析器来解析的

3. 依赖分析

4. 源码分析

4.1. xml说明

在spring中配置了<mvc:interceptors> 标签的会在此解析器中解析得到MappedInterceptor包装类
解析器支持解析三种标签bean,ref,interceptor,从后面源码可以看出来

1
2
3
4
5
6
7
8
9
10
11
12
13
<mvc:interceptors>
<!--在这里创建一个拦截器bean-->
<bean class="com.kewen.interceptor.GlobalInterceptor"/>
<!--引用已有的bean-->
<ref bean="globalInterceptor"/>
<!--配置条件拦截器-->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/login"/>
<ref bean="helloInterceptor"/>
<bean class="com.kewen.interceptor.HelloInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>

4.2. 源码解析

4.2.1. 解析xml加载BeanDifinition

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//InterceptorsBeanDefinitionParser.java
public BeanDefinition parse(Element element, ParserContext context) {
context.pushContainingComponent(
new CompositeComponentDefinition(element.getTagName(), context.extractSource(element)));

RuntimeBeanReference pathMatcherRef = null;
if (element.hasAttribute("path-matcher")) {
pathMatcherRef = new RuntimeBeanReference(element.getAttribute("path-matcher"));
}

//拿到对应标签中的元素
List<Element> interceptors = DomUtils.getChildElementsByTagName(element, "bean", "ref", "interceptor");
//循环构造MappedInterceptor的Bean定义
for (Element interceptor : interceptors) {
RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
mappedInterceptorDef.setSource(context.extractSource(interceptor));
mappedInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

ManagedList<String> includePatterns = null;
ManagedList<String> excludePatterns = null;
Object interceptorBean;
if ("interceptor".equals(interceptor.getLocalName())) {
includePatterns = getIncludePatterns(interceptor, "mapping");
excludePatterns = getIncludePatterns(interceptor, "exclude-mapping");
Element beanElem = DomUtils.getChildElementsByTagName(interceptor, "bean", "ref").get(0);
interceptorBean = context.getDelegate().parsePropertySubElement(beanElem, null);
}
else {
interceptorBean = context.getDelegate().parsePropertySubElement(interceptor, null);
}
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, includePatterns);
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, excludePatterns);
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, interceptorBean);

if (pathMatcherRef != null) {
mappedInterceptorDef.getPropertyValues().add("pathMatcher", pathMatcherRef);
}

//注册到beanDefinitionMap中
String beanName = context.getReaderContext().registerWithGeneratedName(mappedInterceptorDef);
context.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, beanName));
}

context.popAndRegisterContainingComponent();
return null;
}

4.2.2. 加载拦截器

RequestMappingHandlerMapping中的初始化上下文中,会加载拦截器

1
2
3
4
5
6
7
8
9
10
11
12
13
public final void setApplicationContext(@Nullable ApplicationContext context) throws BeansException {
if (context == null && !isContextRequired()) {
//......
}
else if (this.applicationContext == null) {
//......
//初始化上下文
initApplicationContext(context);
}
else {
//......
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
protected void initApplicationContext(ApplicationContext context) {
// 初始化
super.initApplicationContext(context);
if (this.servletContext == null && context instanceof WebApplicationContext) {
this.servletContext = ((WebApplicationContext) context).getServletContext();
if (this.servletContext != null) {
initServletContext(this.servletContext);
}
}
}
protected void initApplicationContext(ApplicationContext context) throws BeansException {
initApplicationContext();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@Override
protected void initApplicationContext() throws BeansException {
//空方法,扩展使用
extendInterceptors(this.interceptors);
//从容器中解析出MappedInterceptor
detectMappedInterceptors(this.adaptedInterceptors);
//初始化拦截器
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");
}
//加入拦截器组
this.adaptedInterceptors.add(adaptInterceptor(interceptor));
}
}
}
//转换拦截器,主要转换 WebRequestInterceptor
protected HandlerInterceptor adaptInterceptor(Object interceptor) {
if (interceptor instanceof HandlerInterceptor) {
return (HandlerInterceptor) interceptor;
}
else if (interceptor instanceof WebRequestInterceptor) {
// 转换WebRequestInterceptor
return new WebRequestHandlerInterceptorAdapter((WebRequestInterceptor) interceptor);
}
else {
throw new IllegalArgumentException("Interceptor type not supported: " + interceptor.getClass().getName());
}
}

5. 总结

专门拿一个解析器解析拦截器,注册成BeanDifinition,再通过获取容器Bean,加入到RequestMappingHandlerMapping中

6. 注意事项