zoukankan      html  css  js  c++  java
  • SpringMVC源码情操陶冶-InterceptorsBeanDefinitionParser拦截器解析器

    解析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源码

  • 相关阅读:
    软件概要设计
    Jmter进行Rabbitmq测试
    分布式锁
    实用异常
    异常集合
    本地Windows环境安装RabbitMQ Server
    MySQL千万级多表关联SQL语句调优
    mysql数据库多表关联查询的慢SQL优化
    rabbitmq详细配置
    Idea连接服务器docker并部署代码到docker实现一键启动
  • 原文地址:https://www.cnblogs.com/question-sky/p/7077788.html
Copyright © 2011-2022 走看看