Insight mvc:interceptor 解析、执行顺序

疑问:在mvc:interceptor 实际使用过程中,interceptor的执行顺序是依赖配置顺序吗,这样引出以下问题。

1、mvc:interceptor 配置怎样解析、初始化?

2、springmvc 处理请求的过程中,interceptors怎样工作的?

...

Insight结论:interceptor的执行顺序就在mvc:interceptor 配置解析时决定,依赖配置顺序。

...

Insight过程:

Insight spring源码,按照以往的分析,mvc:xxx配置的解析由MvcNamespaceHandler 完成。

1、配置解析,以下代码列出了mvc:interceptor解析以及注册到bean-factory的过程。


// 1.MvcNamespaceHandler 注册mvc:interceptor 解析器
registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());
// 2.InterceptorsBeanDefinitionParser 解析Element 并构造MappedInterceptor
// 构造函数:MappedInterceptor(String[] includePatterns, String[] excludePatterns, HandlerInterceptor interceptor)
// 3.register this MappedInterceptor as Element 解析顺序
String beanName = parserContext.getReaderContext().registerWithGeneratedName(mappedInterceptorDef);


/**
 * core! 参考DefaultListableBeanFactory 实现
 * List of bean definition names, in registration order 
 */
private final List
   
   
    
     beanDefinitionNames = new ArrayList
    
    
     
     (64);
    
    
   
   
...

2、interceptor 初始化(将bean-factory解析的MappedInterceptor 注入AbstractHandlerMapping)

public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport {

	private final List
   
   
    
     mappedInterceptors = new ArrayList
    
    
     
     ();

	/**
	 * Initializes the interceptors.
	 * @see ApplicationContextAwareProcessor.postProcessBeforeInitialization 调用该方法 
	 */
	@Override
	protected void initApplicationContext() throws BeansException {
		extendInterceptors(this.interceptors);
		detectMappedInterceptors(this.mappedInterceptors);
		initInterceptors();
	}

	/**
	 * Detect beans of type MappedInterceptor and add them to the list of mapped interceptors.
	 * 该结果来源于bean-factory beanDefinitionNames 顺序仍然不变! 
	 */
	protected void detectMappedInterceptors(List
     
     
      
       mappedInterceptors) {
		mappedInterceptors.addAll(
		    BeanFactoryUtils.beansOfTypeIncludingAncestors(getApplicationContext(), MappedInterceptor.class, true, false).values()
		);
	}

	/**
	 * Look up a handler for the given request, falling back to the default
	 * handler if no specific one is found.
	 */
	public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		Object handler = getHandlerInternal(request);
		if (handler == null) {
			handler = getDefaultHandler();
		}
		if (handler == null) {
			return null;
		}
		// Bean name or resolved handler?
		if (handler instanceof String) {
			String handlerName = (String) handler;
			handler = getApplicationContext().getBean(handlerName);
		}
		return getHandlerExecutionChain(handler, request);
	}

	/**
	 * Build a HandlerExecutionChain for the given handler, including
	 * applicable interceptors.
	 * The default implementation builds a standard HandlerExecutionChain
	 * with the given handler, the handler mapping's common interceptors, and any
	 * MappedInterceptors matching to the current request URL.
	 */
	protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
		HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
		chain.addInterceptors(getAdaptedInterceptors());

		String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
		for (MappedInterceptor mappedInterceptor : this.mappedInterceptors) {
			if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
				chain.addInterceptor(mappedInterceptor.getInterceptor());
			}
		}

		return chain;
	}

}
     
     
    
    
   
   

...

3、interceptors 工作的过程:

参考上述的源码,遍历HandlerMapping.mappedInterceptors,根据request path匹配符合的拦截器。

也就是说:DispatcherServlet处理请求

getHandler per request

匹配拦截器  per request

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值