解析mvc:interceptors节点

观察下InterceptorsBeanDefinitionParser的源码备注

/**
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses a
* {@code interceptors} element to register a set of {@link MappedInterceptor} definitions.
*
* @author Keith Donald
* @since 3.0
*/

从官方注释可知,此解析器的作用是解析mvc:interceptors节点并注册成MappedInterceptorsDefinition集合

mvc:interceptors的配置使用

    <!-- 拦截器设置 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<!-- 静态资源不拦截 -->
<mvc:exclude-mapping path="/mobile/**"/>
<mvc:exclude-mapping path="/pc/**"/>
<!-- 主页不拦截 --> <!-- 特殊user资源获取不拦截 -->
<bean class="com.du.wx.interceptor.UserInterceptor" />
</mvc:interceptor>
</mvc:interceptors>

InterceptorsBeanDefinitionParser#parse

直接观察公用接口方法parse(),源码奉上

	@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
//CompositeComponentDefinition表示其可以装载多个ComponentDefinition
CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compDefinition); //允许mvc:interceptors拥有path-matcher属性,表示 路径匹配解析器
RuntimeBeanReference pathMatcherRef = null;
if (element.hasAttribute("path-matcher")) {
pathMatcherRef = new RuntimeBeanReference(element.getAttribute("path-matcher"));
}
//查询mvc:interceptors节点下的bean/ref/interceptor标签
List<Element> interceptors = DomUtils.getChildElementsByTagName(element, "bean", "ref", "interceptor");
for (Element interceptor : interceptors) {
//采用MappedInterceptor作为beanClass
RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
mappedInterceptorDef.setSource(parserContext.extractSource(interceptor));
mappedInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); ManagedList<String> includePatterns = null;
ManagedList<String> excludePatterns = null;
Object interceptorBean;
//解析mvc:interceptor节点
if ("interceptor".equals(interceptor.getLocalName())) {
//解析mvc:mapping节点中的path属性,保存里面的拦截路径集合
includePatterns = getIncludePatterns(interceptor, "mapping");
//解析mvc:exclude-mapping节点中的path属性,保存里面的放行路径集合
excludePatterns = getIncludePatterns(interceptor, "exclude-mapping");
//解析bean标签/ref标签,并封装成beanDefinition
Element beanElem = DomUtils.getChildElementsByTagName(interceptor, "bean", "ref").get(0);
interceptorBean = parserContext.getDelegate().parsePropertySubElement(beanElem, null);
}
else {
//解析bean标签/ref标签,并封装成beanDefinition
interceptorBean = parserContext.getDelegate().parsePropertySubElement(interceptor, null);
}
//MappedInterceptor类的构造函数可接受三个参数
/**
**public MappedInterceptor(String[] includePatterns, String[] excludePatterns, HandlerInterceptor interceptor)
**
*/
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, includePatterns);
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, excludePatterns);
mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, interceptorBean);
//为MappedInterceptor添加pathMatcher属性
if (pathMatcherRef != null) {
mappedInterceptorDef.getPropertyValues().add("pathMatcher", pathMatcherRef);
}
//保存到spring的bean工厂中
String beanName = parserContext.getReaderContext().registerWithGeneratedName(mappedInterceptorDef);
parserContext.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, beanName));
} parserContext.popAndRegisterContainingComponent();
return null;
}

小结

  • 解析mvc:interceptors,其会封装为MappedInterceptor类,进而保存
  1. 拦截路径匹配集合includePatterns
  2. 不拦截路径匹配集合excludePatterns
  3. 拦截处理器interceptor,其必须是HandlerInterceptor的实现类
  4. 路径匹配处理器,如果mvc:interceptors设定了path-matcher属性,默认为AntPathMatcher
  • MappedInterceptor其内部包含了HandlerInterceptor集合,并添加了路径的映射属性。对匹配的路径调用相应的HandlerInterceptors

  • mvc:interceptors注册的拦截器在AbstractHandlerMapping类中通过matches()方法被调用,具体调用见Springmvc源码

SpringMVC源码情操陶冶-InterceptorsBeanDefinitionParser拦截器解析器的更多相关文章

  1. SpringMVC源码情操陶冶-ResourcesBeanDefinitionParser静态资源解析器

    解析mvc:resources节点,控制对静态资源的映射访问 查看官方注释 /** * {@link org.springframework.beans.factory.xml.BeanDefinit ...

  2. Spring源码情操陶冶-AnnotationConfigBeanDefinitionParser注解配置解析器

    本文承接前文Spring源码情操陶冶-自定义节点的解析,分析spring中的context:annotation-config节点如何被解析 源码概览 对BeanDefinitionParser接口的 ...

  3. Spring源码情操陶冶-ComponentScanBeanDefinitionParser文件扫描解析器

    承接前文Spring源码情操陶冶-自定义节点的解析,本文讲述spring通过context:component-scan节点干了什么事 ComponentScanBeanDefinitionParse ...

  4. Spring源码情操陶冶-PropertyPlaceholderBeanDefinitionParser注解配置解析器

    本文针对spring配置的context:property-placeholder作下简单的分析,承接前文Spring源码情操陶冶-自定义节点的解析 spring配置文件应用 <context: ...

  5. Spring源码情操陶冶-AOP之ConfigBeanDefinitionParser解析器

    aop-Aspect Oriented Programming,面向切面编程.根据百度百科的解释,其通过预编译方式和运行期动态代理实现程序功能的一种技术.主要目的是为了程序间的解耦,常用于日志记录.事 ...

  6. SpringMVC源码情操陶冶-HandlerAdapter适配器简析

    springmvc中对业务的具体处理是通过HandlerAdapter适配器操作的 HandlerAdapter接口方法 列表如下 /** * Given a handler instance, re ...

  7. Spring源码情操陶冶-自定义节点的解析

    本文承接前文Spring源码情操陶冶-DefaultBeanDefinitionDocumentReader#parseBeanDefinitions,特开辟出一块新地来啃啃这块有意思的骨头 自定义节 ...

  8. SpringMVC源码情操陶冶-AnnotationDrivenBeanDefinitionParser注解解析器

    mvc:annotation-driven节点的解析器,是springmvc的核心解析器 官方注释 Open Declaration org.springframework.web.servlet.c ...

  9. SpringMVC源码情操陶冶#task-executor解析器

    承接Spring源码情操陶冶-自定义节点的解析.线程池是jdk的一个很重要的概念,在很多的场景都会应用到,多用于处理多任务的并发处理,此处借由spring整合jdk的cocurrent包的方式来进行深 ...

随机推荐

  1. 2017年浙江理工大学程序设计竞赛校赛 题解&源码(A.水, D. 简单贪心 ,E.数论,I 暴力)

    Problem A: 回文 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 1719  Solved: 528 Description 小王想知道一个字 ...

  2. 2017 Multi-University Training Contest - Team 1 1001&&HDU 6033 Add More Zero【签到题,数学,水】

    Add More Zero Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  3. BZOJ 1192: [HNOI2006]鬼谷子的钱袋(新生必做的水题)

    1192: [HNOI2006]鬼谷子的钱袋 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3557  Solved: 2596[Submit][St ...

  4. HDU 2079 dp解法

    选课时间(题目已修改,注意读题) Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  5. 安装myeclipse后,打开时弹出:“该站点安全证书的吊销证书不可用”,怎样解决?

    1.当弹出"该站点安全证书的吊销信息不可用.是否继续?"的对话框时,点击"查看证书",切换到"详细信息"TAB页,找到其"CRL分 ...

  6. Linux 文件操作命令-Linux基础环境命令学习笔记

    1.文件目录操作 1)路径识别 a.绝对路径,以根目录开始 b.相对路径,以当前目录开始,不需从根目录开始写起 2)命令 man ls 查看ls命令帮助 cd /var/log 切换进入log目录(. ...

  7. 一.初识java

    1.框架结构 2.main方法 3.转义符 public class Dome01 { public static void main(String[] args) {       //main方法, ...

  8. sqlite数据库的char,varchar,text,nchar,nvarchar,ntext的区别

    1.CHAR.CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比如定义char(10),那么不论你存储的数据是否达到了10个字节,都要占去10个字节的空间,不足的自动用空格填充. 2.VAR ...

  9. 使用 EclEmma 进行覆盖测试

    开源软件测试工具 EclEmma,它能够对由 Java 语言编写的程序进行覆盖测试,从而对程序运行的结果生成详尽的覆盖测试报告. UT-Junit 安装 EclEmma 插件 安装 EclEmma 插 ...

  10. vue+springboot前后端分离实现单点登录跨域问题处理

    最近在做一个后台管理系统,前端是用时下火热的vue.js,后台是基于springboot的.因为后台系统没有登录功能,但是公司要求统一登录,登录认证统一使用.net项目组的认证系统.那就意味着做单点登 ...