转自:
HandlerMapping类是如何找到相应的controller呢?
下文笔者讲述HandlerMapping类通过Mapping找到相应Controller的方法分享,如下所示:
HandlerMapping在SpringMVC中的作用:
完成url和Controller之间映射
注意事项:
当HandlerMapping的匹配关系无法满足我们的规则时,我们可实现HandlerMapping接口对其进行扩展
HandlerMapping的组成部分
HandlerMapping由:HandlerMapping映射注册、根据url获取对应的处理器、拦截器注册三部分组成
HandlerMapping原理
HandlerMapping接口定义
package org.springframework.web.servlet; public interface HandlerMapping { HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception; }
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)