SpringMVC源码情操陶冶-AbstractHandlerMapping
2017-07-06 14:57
387 查看
分析下springmvc的HandlerMapping映射的抽象类
初始化操作
通过initApplicationContext()方法进行初始化,其一般是由父类执行
ApplicationContextAware#setApplicationContext()方法间接调用,源码奉上
protected void initApplicationContext() throws BeansException { //供子类扩展添加拦截器,目前spring没有自行实现 extendInterceptors(this.interceptors); //搜寻springmvc中的MappedInterceptors保存至adaptedInterceptors集合 detectMappedInterceptors(this.adaptedInterceptors); //将interceptors集合添加至adaptedInterceptors集合中 initInterceptors(); }
主要目的是获取
springmvc上下文中的拦截器集合,此处特指
MappedInterceptor
AbstractHandlerMapping#getHandler()-获取处理链对象
源码奉上public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { //getHandlerInternal(request)方法为抽象方法,供子类实现 //获取到的handler对象一般为bean/HandlerMethod Object handler = getHandlerInternal(request); //上述找不到则使用默认的处理类,没有设定则返回null,则会返回前台404错误 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); } //创建处理链对象 HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); //针对cros跨域请求的处理,此处就不分析了 if (CorsUtils.isCorsRequest(request)) { CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request); CorsConfiguration handlerConfig = getCorsConfiguration(handler, request); CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig); executionChain = getCorsHandlerExecutionChain(request, executionChain, config); } return executionChain; }
由以上代码分析可知,需要观察下如何获取handler对象以及创建HandlerExecutionChain处理链对象
AbstractHandlerMethodMapping#getHandlerInternal()-针对HandlerMethod的获取
主要是解析@Controller注解类中的
@RequestMapping方法得到其中的HandlerMethod对象作为返回的Handler
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception { //获取访问的路径,一般类似于request.getServletPath()返回不含contextPath的访问路径 String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); //获取读锁 this.mappingRegistry.acquireReadLock(); try { //获取HandlerMethod作为handler对象,这里涉及到路径匹配的优先级 //优先级:精确匹配>最长路径匹配>扩展名匹配 HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request); //HandlerMethod内部含有bean对象,其实指的是对应的Controller return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null); } finally { //释放读锁 this.mappingRegistry.releaseReadLock(); } }
AbstractUrlHandlerMapping#getHandlerInternal()-针对beanName的获取
源码奉上,此处的逻辑就较为简单了protected Object getHandlerInternal(HttpServletRequest request) throws Exception { String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); //从handlerMap查找路径对应的beanName Object handler = lookupHandler(lookupPath, request); if (handler == null) { // We need to care for the default handler directly, since we need to // expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well. Object rawHandler = null; if ("/".equals(lookupPath)) { rawHandler = getRootHandler(); } if (rawHandler == null) { rawHandler = getDefaultHandler(); } if (rawHandler != null) { // Bean name or resolved handler? if (rawHandler instanceof String) { String handlerName = (String) rawHandler; rawHandler = getApplicationContext().getBean(handlerName); } validateHandler(rawHandler, request); handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null); } } return handler; }
AbstractHandlerMapping#getHandlerExecutionChain()-创建处理链对象
先附上HandlerExecutionChain的内部属性//真实处理请求对象 private final Object handler; //拦截器集合 private HandlerInterceptor[] interceptors; //拦截器集合 private List<HandlerInterceptor> interceptorList; //拦截器开始下标,默认正序执行 private int interceptorIndex = -1;
再奉上创建处理链对象的源码
//此处的handler可为HandlerMethod/beanName protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? (HandlerExecutionChain) handler : new HandlerExecutionChain(handler)); String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); for (HandlerInterceptor interceptor : this.adaptedInterceptors) { if (interceptor instanceof MappedInterceptor) { MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor; if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) { chain.addInterceptor(mappedInterceptor.getInterceptor()); } } else { chain.addInterceptor(interceptor); } } return chain; }
处理链的创建基本就是 带有handler对象以及添加拦截器对象集合,用于后期的拦截
HandlerExecutionChain处理链内部含有handler对象,可为
@RequestMapping对应的HandlerMethod对象,也可为springmvc上下文的beanName
HandlerExecutionChain处理链内部主要包含拦截器对象,其可从springmvc上下文获取
HandlerInterceptor/
MappedHandlerInterceptor类型作为内部集合;
当然此处获得拦截器集合也是根据路径匹配获取的,比如
mvc:interceptor指定的或者
mvc:resource指定的
小结
相关文章推荐
- SpringMVC源码情操陶冶-AbstractHandlerMethodMapping
- SpringMVC源码情操陶冶-AbstractUrlHandlerMapping
- SpringMVC源码情操陶冶-AbstractHandlerExceptionResolver
- springMVC源码分析--AbstractUrlHandlerMapping(三)
- springMVC源码分析--AbstractDetectingUrlHandlerMapping(五)
- springMVC源码分析--AbstractHandlerMethodMapping获取url和HandlerMethod对应关系(十)
- springMVC源码分析--AbstractHandlerMethodMapping注册url和HandlerMethod对应关系(十一)
- SpringMVC源码解读 - HandlerMapping - AbstractDetectingUrlHandlerMapping系列初始化
- springMVC源码分析--AbstractControllerUrlHandlerMapping(六)
- SpringMVC源码解读之HandlerMapping - AbstractUrlHandlerMapping系列request分发
- springMVC源码分析--AbstractControllerUrlHandlerMapping(六)
- SpringMVC源码解读之 HandlerMapping - AbstractDetectingUrlHandlerMapping系列初始化