HandlerMapping执行原理,如何找到controller

HandlerMapping在这个SpringMVC体系结构中有着举足轻重的地位,充当着url和Controller之间映射关系配置的角色。HandlerMapping是接口,Spring MVC提供了一系列HandlerMapping的实现,根据一定的规则选择controller。如果当前的HandlerMappign实现中没有能够满足你所需要的规则是,可以通过实现HandlerMapping接口进行扩展。它主要有三部分组成:HandlerMapping映射注册、根据url获取对应的处理器、拦截器注册。

HandlerMapping执行流程

HandlerMapping执行流程

HandlerMapping原理

1. HandlerMapping接口定义

package org.springframework.web.servlet;
public interface HandlerMapping {
	HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}

2. AbstractHandlerMapping实现接口

AbstractHandlerMapping属性

// order赋了最大值,优先级是最小的
private int order = Integer.MAX_VALUE;  // default: same as non-Ordered
// 默认的Handler,这边使用的Obejct,子类实现的时候,使用HandlerMethod,HandlerExecutionChain等
private Object defaultHandler;
// url计算的辅助类
private UrlPathHelper urlPathHelper = new UrlPathHelper();
// 基于ant进行path匹配,解决如/books/{id}场景
private PathMatcher pathMatcher = new AntPathMatcher();
// 拦截器配置:1,HandlerMapping属性设置;2,extendInterceptors设置
private final Listinterceptors = new ArrayList();
// 从interceptors中解析得到,直接添加给全部handler
private final ListadaptedInterceptors = new ArrayList();
// 使用前需要跟url进行匹配,匹配通过才会使用
private final ListmappedInterceptors = new ArrayList();

AbstractHandlerMapping拦截器初始化

@Override
protected void initApplicationContext() throws BeansException {
    extendInterceptors(this.interceptors);
    detectMappedInterceptors(this.mappedInterceptors);
    initInterceptors();
}

/**
 * 提供给子类扩展拦截器,可惜都没有使用
 */
protected void extendInterceptors(Listinterceptors) {
}

/**
 * 扫描应用下的MappedInterceptor,并添加到mappedInterceptors
 */
protected void detectMappedInterceptors(ListmappedInterceptors) {
    mappedInterceptors.addAll(
            BeanFactoryUtils.beansOfTypeIncludingAncestors(
                    getApplicationContext(),MappedInterceptor.class, true, false).values());
}

/**
 * 归集MappedInterceptor,并适配HandlerInterceptor和WebRequestInterceptor
 */
protected void initInterceptors() {
    if (!this.interceptors.isEmpty()) {
        for (int i = 0; i < this.interceptors.size(); i++) { 
            Object interceptor = this.interceptors.get(i); 
            if (interceptor == null) { throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null"); } 
            if (interceptor instanceof MappedInterceptor) { mappedInterceptors.add((MappedInterceptor) interceptor); } 
            else { adaptedInterceptors.add(adaptInterceptor(interceptor)); } } } } 

protected HandlerInterceptor adaptInterceptor(Object interceptor) { 
    if (interceptor instanceof HandlerInterceptor) { return (HandlerInterceptor) interceptor; } 
    else if (interceptor instanceof WebRequestInterceptor) { return new WebRequestHandlerInterceptorAdapter((WebRequestInterceptor) interceptor); } 
    else { throw new IllegalArgumentException("Interceptor type not supported: " + interceptor.getClass().getName()); } } 

3. getHandler实现

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);
}
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
    HandlerExecutionChain chain =
        (handler instanceof HandlerExecutionChain) ?
            (HandlerExecutionChain) handler : new HandlerExecutionChain(handler);

    chain.addInterceptors(getAdaptedInterceptors());

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

    return chain;
}

封装拦截器到HandlerExecutionChain,HandlerExecutionChain中只包含一个handler。包含N个拦截器,把这个对象返回给了中央调度器。其中adaptedInterceptors是直接添加,mappedInterceptors需要根据url匹配通过后添加

HandlerMapping总结

HandlerMapping是处理器映射器,根据请求找到处理器Handler,但并不是简单的返回处理器,而是将处理器和拦截器封装,形成一个处理器执行链(HandlerExecuteChain)。

HandlerMapping执行流程如下:
DispatcherServlet
--->doDispatcher()
---->getHandler(request):
---->HandlerExecutionChain
------> hm.getHandler(request)-----》方法体中
----->ExecutionChain executionChain = getHandlerExecutionChain(handler, request);
----->new HandlerExecutionChain(handler)
----->chain.addInterceptor(interceptor);

版权声明:本文为JAVASCHOOL原创文章,未经本站允许不得转载。