解析mvc:interceptors节点

观察下InterceptorsBeanDefinitionParser的源码备注

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

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

mvc:interceptors的配置使用

  1. <!-- 拦截器设置 -->
  2. <mvc:interceptors>
  3. <mvc:interceptor>
  4. <mvc:mapping path="/**"/>
  5. <!-- 静态资源不拦截 -->
  6. <mvc:exclude-mapping path="/mobile/**"/>
  7. <mvc:exclude-mapping path="/pc/**"/>
  8. <!-- 主页不拦截 -->
  9. <!-- 特殊user资源获取不拦截 -->
  10. <bean class="com.du.wx.interceptor.UserInterceptor" />
  11. </mvc:interceptor>
  12. </mvc:interceptors>

InterceptorsBeanDefinitionParser#parse

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

  1. @Override
  2. public BeanDefinition parse(Element element, ParserContext parserContext) {
  3. //CompositeComponentDefinition表示其可以装载多个ComponentDefinition
  4. CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
  5. parserContext.pushContainingComponent(compDefinition);
  6. //允许mvc:interceptors拥有path-matcher属性,表示 路径匹配解析器
  7. RuntimeBeanReference pathMatcherRef = null;
  8. if (element.hasAttribute("path-matcher")) {
  9. pathMatcherRef = new RuntimeBeanReference(element.getAttribute("path-matcher"));
  10. }
  11. //查询mvc:interceptors节点下的bean/ref/interceptor标签
  12. List<Element> interceptors = DomUtils.getChildElementsByTagName(element, "bean", "ref", "interceptor");
  13. for (Element interceptor : interceptors) {
  14. //采用MappedInterceptor作为beanClass
  15. RootBeanDefinition mappedInterceptorDef = new RootBeanDefinition(MappedInterceptor.class);
  16. mappedInterceptorDef.setSource(parserContext.extractSource(interceptor));
  17. mappedInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
  18. ManagedList<String> includePatterns = null;
  19. ManagedList<String> excludePatterns = null;
  20. Object interceptorBean;
  21. //解析mvc:interceptor节点
  22. if ("interceptor".equals(interceptor.getLocalName())) {
  23. //解析mvc:mapping节点中的path属性,保存里面的拦截路径集合
  24. includePatterns = getIncludePatterns(interceptor, "mapping");
  25. //解析mvc:exclude-mapping节点中的path属性,保存里面的放行路径集合
  26. excludePatterns = getIncludePatterns(interceptor, "exclude-mapping");
  27. //解析bean标签/ref标签,并封装成beanDefinition
  28. Element beanElem = DomUtils.getChildElementsByTagName(interceptor, "bean", "ref").get(0);
  29. interceptorBean = parserContext.getDelegate().parsePropertySubElement(beanElem, null);
  30. }
  31. else {
  32. //解析bean标签/ref标签,并封装成beanDefinition
  33. interceptorBean = parserContext.getDelegate().parsePropertySubElement(interceptor, null);
  34. }
  35. //MappedInterceptor类的构造函数可接受三个参数
  36. /**
  37. **public MappedInterceptor(String[] includePatterns, String[] excludePatterns, HandlerInterceptor interceptor)
  38. **
  39. */
  40. mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(0, includePatterns);
  41. mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, excludePatterns);
  42. mappedInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(2, interceptorBean);
  43. //为MappedInterceptor添加pathMatcher属性
  44. if (pathMatcherRef != null) {
  45. mappedInterceptorDef.getPropertyValues().add("pathMatcher", pathMatcherRef);
  46. }
  47. //保存到spring的bean工厂中
  48. String beanName = parserContext.getReaderContext().registerWithGeneratedName(mappedInterceptorDef);
  49. parserContext.registerComponent(new BeanComponentDefinition(mappedInterceptorDef, beanName));
  50. }
  51. parserContext.popAndRegisterContainingComponent();
  52. return null;
  53. }

小结

  • 解析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. COGS 862. 二进制数01串【dp+经典二分+字符串】

    862. 二进制数01串 ★   输入文件:kimbits.in   输出文件:kimbits.out   简单对比 时间限制:1 s   内存限制:128 MB USACO/kimbits(译 by ...

  2. c++(hash表)

    hash表,有时候也被称为散列表.个人认为,hash表是介于链表和二叉树之间的一种中间结构.链表使用十分方便,但是数据查找十分麻烦:二叉树中的数据严格有序,但是这是以多一个指针作为代价的结果.hash ...

  3. c++(排序二叉树)

    前面我们讲过双向链表的数据结构.每一个循环节点有两个指针,一个指向前面一个节点,一个指向后继节点,这样所有的节点像一颗颗珍珠一样被一根线穿在了一起.然而今天我们讨论的数据结构却有一点不同,它有三个节点 ...

  4. 用于 C&sharp; 图像识别的轮廓分析技术

    用于 C♯ 图像识别的轮廓分析技术 供稿:Conmajia 标题:Contour Analysis for Image Recognition in C# 作者:Pavel Torgashov 此中文 ...

  5. 什么是A记录/CNAME记录/MX记录/TXT记录

    答: A 记录(Address)是用来指定主机名(或域名)对应的IP地址记录.当你输入域名的时候给你引导向设置在DNS的A记录所对应的服务器. CNAME记录 ( Canonical Name )是一 ...

  6. 独立服务器 云主机、VPS以及虚拟主机三者之间的区别是什么?哪个更好?

    https://www.zhihu.com/question/21442353#answer-2442764 云主机(如 EC2,[1] )和 VPS (如 Linode,[2])都是完整的操作系统( ...

  7. MySQL密码忘了怎么办?MySQL重置root密码方法

    本文主要介绍Windows和Linux系统下忘记密码重置root密码的方法,需要的朋友可以参考下. MySQL有时候忘记了root密码是一件伤感的事.这里提供Windows 和 Linux 下的密码重 ...

  8. 新版Azure Automation Account 浅析(二) --- 更新Powershell模块和创建Runbook

    前篇我们讲了怎样创建一个自动化账户以及创建时候"Run As Account"选项背后的奥秘.这一篇针对在Azure自动化账户中使用Powershell Runbook的用户讲一下 ...

  9. Mysql Order By 字符串排序,mysql 字符串order by

    Mysql Order By 字符串排序,mysql 字符串order by ============================== ©Copyright 蕃薯耀 2017年9月30日 http ...

  10. JS中获取session中传过来的值对象

    摘录自:http://www.360doc.com/content/11/0316/13/5790498_101627263.shtml 把某一对象置于session范围内,并在JSP页面中提取ses ...