解析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. BZOJ 1411&&Vijos 1544 : [ZJOI2009]硬币游戏【递推,快速幂】

    1411: [ZJOI2009]硬币游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 897  Solved: 394[Submit][Status ...

  2. BLE空中升级 谈(二)

    BLE 空中升级谈 -- CC2541 的产品开发中OAD注意事项(续) TI CC2541支持多个硬件,多个软件对它进行空中升级,可以有不同的组合,硬件有 编号 名称 Hex 用法 1 Cc2540 ...

  3. mitm6:通过IPv6攻破IPv4网络

    一.前言 虽然IPv6正在互联网上逐步推广,但在内部网络环境中使用IPv6的公司依然非常稀少.然而,大多数公司并不知道,即使他们没有主动去使用IPv6,但从Windows Vista以来,所有的Win ...

  4. HDU 1069 Monkey and Banana(DP——最大递减子序列)

    题目链接: http://acm.split.hdu.edu.cn/showproblem.php?pid=1069 题意描述: 给n块砖,给出其长,宽和高 问将这n块砖,怎样叠放使得满足以下条件使得 ...

  5. 算法-java代码实现堆排序

    堆排序 第7节 堆排序练习题 对于一个int数组,请编写一个堆排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3],6 [1,2 ...

  6. iOS学习——键盘弹出遮挡输入框问题解决方案

    在iOS或Android等移动端开发过程中,经常遇到很多需要我们输入信息的情况,例如登录时要输入账号密码.查询时要输入查询信息.注册或申请时需要填写一些信息等都是通过我们键盘来进行输入的,在iOS开发 ...

  7. Oracle:对用户的CREATE、ALTER、GRANT、REVOKE操作练习

    --创建一个用户yong2,yong2的表空间为users,临时表空间为temp,users的表空间大小为10M,密码立刻过期,用户锁定. CREATE USER yong2IDENTIFIED BY ...

  8. PHP move_uploaded_file() 函数

    PHP Filesystem 函数 定义和用法 move_uploaded_file() 函数将上传的文件移动到新位置. 若成功,则返回 true,否则返回 false. 语法 move_upload ...

  9. J.U.C CAS

    在JDK1.5之前,也就是J.U.C加入JDK之前,Java是依靠synchronized关键字(JVM底层提供)来维护协调对共享字段的访问,保证对这些变量的独占访问权,并且以后其他线程忽的该锁时,将 ...

  10. Laravel的unique和exists验证规则的优化

    本文是Laravel实战:任务管理系统(一)的扩展阅读 原文链接:http://pilishen.com/posts/Improvements-to-the-Laravel-unique-and-ex ...