handlerMapping的初始化以及查找handler

关山初度尘未洗,策马扬鞭再奋蹄!这篇文章主要讲述handlerMapping的初始化以及查找handler相关的知识,希望能为你提供帮助。

前提:HttpServletBean初始化了一些servlet配置,接着FrameWorkServlet创建了WebApplicationContext,最后DispatcherServlet初始化一些解析器,mapping(九大组件)。一、从DispatcherServlet的doDispatch开始。 但WebApplicationContext加载完毕后FrameWorkdServlet调用DispatcherServlet的onRefresh方法 @Override protected void onRefresh(ApplicationContext context) { initStrategies(context); } initStrategies方法如下: protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); } 这里初始化了九大组件,如果在初始化组件的时候没有明确规定使用那个组件时,会使用默认策略。现在我们只关心initHandlerMappings(context); 这个方法 private void initHandlerMappings(ApplicationContext context) { this.handlerMappings = null; if (this.detectAllHandlerMappings) { // Find all HandlerMappings in the ApplicationContext, including ancestor contexts. //从applicationContext获取HandlerMapping.class类型的bean Map< String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false); if (!matchingBeans.isEmpty()) { this.handlerMappings = new ArrayList< HandlerMapping> (matchingBeans.values()); // We keep HandlerMappings in sorted order. AnnotationAwareOrderComparator.sort(this.handlerMappings); } } else { try { HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class); this.handlerMappings = Collections.singletonList(hm); } catch (NoSuchBeanDefinitionException ex) { // Ignore, we‘ll add a default HandlerMapping later. } }// Ensure we have at least one HandlerMapping, by registering // a default HandlerMapping if no other mappings are found. if (this.handlerMappings == null) { this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class); if (logger.isDebugEnabled()) { logger.debug("No HandlerMappings found in servlet ‘" + getServletName() + "‘: using default"); } } }将找到的HandlerMapping全部存到DispatcherServlet的this.handlerMappings中二、doDispatch方法 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { ModelAndView mv = null; Exception dispatchException = null; try { processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); // Determine handler for the current request.通过request获取HandlerExecutionChain,这个执行链中保存了handler和需要做拦截的拦截器 mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; }// Determine handler adapter for the current request.通过handler寻找能够处理这个handler的handlerAdapter。 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler. String method = request.getMethod(); boolean isGet = "GET".equals(method); if (isGet || "HEAD".equals(method)) { long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if (logger.isDebugEnabled()) { logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified); } if (new ServletWebRequest(request, response).checkNotModified(lastModified) & & isGet) { return; } }if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; }// Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; }applyDefaultViewName(processedRequest, mv); mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Error err) { triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err); } finally { if (asyncManager.isConcurrentHandlingStarted()) { // Instead of postHandle and afterCompletion if (mappedHandler != null) { mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } } else { // Clean up any resources used by a multipart request. if (multipartRequestParsed) { cleanupMultipart(processedRequest); } } } }来看看getHandler方法 protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { for (HandlerMapping hm : this.handlerMappings) { if (logger.isTraceEnabled()) { logger.trace( "Testing handler map [" + hm + "] in DispatcherServlet with name ‘" + getServletName() + "‘"); } //遍历所有的HandlerMapping,如果这个handlerMapping能够找到handler,那么就会返回 HandlerExecutionChain handler = hm.getHandler(request); if (handler != null) { return handler; } } return null; }//调用handlerMpping的getHandler方法 @Override public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { //调用模板方法getHandlerInternal,这个方法由子类实现 Object handler = getHandlerInternal(request); if (handler == null) { handler = getDefaultHandler(); } if (handler == null) { return null; } // Bean name or resolved handler?如果是String类型就从applicationContext中查找 if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } //获取处理器链,内部在构造HandlerExecutionChain的同时会查找符合条件的拦截器 HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); 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; }AbstractHandlerMethodMapping的继承结构:这个处理器映射是用来查找方法处理器AbstractUrlHandlerMapping:这种处理器是通过url来查找handler的,比如我们在配置文件中配置 < bean name=‘‘/index" class="com.test.indexContrller" /> 它的url是/index,如果有比较复杂的,那么就会使用PatchMatcher来匹配url,如果匹配就返回对应的handler。@Override public void initApplicationContext() throws BeansException { super.initApplicationContext(); registerHandlers(this.urlMap); }初始化initApplicationContext方法初始化了一些拦截器。 registerHandlers注册了处理器。protected void registerHandlers(Map< String, Object> urlMap) throws BeansException { if (urlMap.isEmpty()) { logger.warn("Neither ‘urlMap‘ nor ‘mappings‘ set on SimpleUrlHandlerMapping"); } else { for (Map.Entry< String, Object> entry : urlMap.entrySet()) { String url = entry.getKey(); Object handler = entry.getValue(); // Prepend with slash if not already present. if (!url.startsWith("/")) { url = "/" + url; } // Remove whitespace from handler bean name. if (handler instanceof String) { handler = ((String) handler).trim(); } registerHandler(url, handler); } } }protected void registerHandler(String urlPath, Object handler) throws BeansException, IllegalStateException { Assert.notNull(urlPath, "URL path must not be null"); Assert.notNull(handler, "Handler object must not be null"); Object resolvedHandler = handler; // Eagerly resolve handler if referencing singleton via name. if (!this.lazyInitHandlers & & handler instanceof String) { String handlerName = (String) handler; if (getApplicationContext().isSingleton(handlerName)) { resolvedHandler = getApplicationContext().getBean(handlerName); } }Object mappedHandler = this.handlerMap.get(urlPath); if (mappedHandler != null) { if (mappedHandler != resolvedHandler) { throw new IllegalStateException( "Cannot map " + getHandlerDescription(handler) + " to URL path [" + urlPath + "]: There is already " + getHandlerDescription(mappedHandler) + " mapped."); } } else { if (urlPath.equals("/")) { if (logger.isInfoEnabled()) { logger.info("Root mapping to " + getHandlerDescription(handler)); } setRootHandler(resolvedHandler); } else if (urlPath.equals("/*")) { if (logger.isInfoEnabled()) { logger.info("Default mapping to " + getHandlerDescription(handler)); } setDefaultHandler(resolvedHandler); } else { this.handlerMap.put(urlPath, resolvedHandler); if (logger.isInfoEnabled()) { logger.info("Mapped URL path [" + urlPath + "] onto " + getHandlerDescription(handler)); } } } }以UrlPath handler的方式存入map。@Override protected Object getHandlerInternal(HttpServletRequest request) throws Exception { //获取出去了ContextPath的uri String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); 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; //如果是web Contextpath的根路径就直接获取根处理器,这个处理器在registHandler方法时就set进去了 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); } } if (handler != null & & logger.isDebugEnabled()) { logger.debug("Mapping [" + lookupPath + "] to " + handler); } else if (handler == null & & logger.isTraceEnabled()) { logger.trace("No handler mapping found for [" + lookupPath + "]"); } return handler; }buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null); 方法是这样的,设置了一些拦截器 protected Object buildPathExposingHandler(Object rawHandler, String bestMatchingPattern, String pathWithinMapping, Map< String, String> uriTemplateVariables) {HandlerExecutionChain chain = new HandlerExecutionChain(rawHandler); chain.addInterceptor(new PathExposingHandlerInterceptor(bestMatchingPattern, pathWithinMapping)); if (!CollectionUtils.isEmpty(uriTemplateVariables)) { chain.addInterceptor(new UriTemplateVariablesHandlerInterceptor(uriTemplateVariables)); } return chain; }查找到handler后通过handler去寻找匹配的handlerAdapter,像simpleHandlerMapping弄出来的handler,其对应的adapter是SimpleControllerHandlerAdapter它有个方法:@Override public boolean supports(Object handler) { return (handler instanceof Controller); } 从这里可以看到它只支持实现了Controller的类。 看到这里其实我们也可以定义自己的HandlerMapping,实现getHandlerInterna方法,从applicationContext中寻找,加入我们自定义一个借口叫做IControllerpackage com.booway.custominterface; import org.springframework.web.servlet.ModelAndView; public interface IController {public ModelAndView IHandlerRequest() throws Exception; }定义一个HandlerMappingpackage com.booway.customhandlermapping; import javax.servlet.http.HttpServletRequest; import org.springframework.util.PathMatcher; import org.springframework.web.servlet.handler.AbstractHandlerMapping; import com.booway.custominterface.IController; public class ISimapleHandlerMapping extends AbstractHandlerMapping {@Override protected Object getHandlerInternal(HttpServletRequest request) throws Exception { String[] beanNames = super.getApplicationContext().getBeanNamesForType(IController.class); String lookupPath = super.getUrlPathHelper().getLookupPathForRequest(request); PathMatcher pathMatcher = getPathMatcher(); for (String beanName : beanNames) { if(pathMatcher.match(beanName, lookupPath)) { return super.getApplicationContext().getBean(beanName); } }return null; }}定义一个adapter package com.booway.customhandleradapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerAdapter; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.mvc.LastModified; import com.booway.custominterface.IController; public class ISimpleHandlerAdapter implements HandlerAdapter {@Override public boolean supports(Object handler) {return handler instanceof IController; }@Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return ((IController)handler).IHandlerRequest(); }@Override public long getLastModified(HttpServletRequest request, Object handler) { if (handler instanceof LastModified) { return ((LastModified) handler).getLastModified(request); } return -1L; }}定义一个controllerpackage com.booway.controller; import org.springframework.web.servlet.ModelAndView; import com.booway.custominterface.IController; public class TestController implements IController {@Override public ModelAndView IHandlerRequest() throws Exception {ModelAndView mav = new ModelAndView(); mav.setViewName("test"); return mav; }}在配置文件中配置响应的bean< bean name="/*" class="com.booway.controller.TestController"> < /bean> < bean id="handlerAdapter" class="com.booway.customhandleradapter.ISimpleHandlerAdapter"> < /bean> < bean id="handlerMapping" class="com.booway.customhandlermapping.ISimapleHandlerMapping"> //定义顺序,防止spring的HandlerMapping处理 < property name="order" value="https://www.songbingjia.com/android/1"> < /property> < /bean> jsp页面 < %@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> < !DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> < html> < head> < meta http-equiv="Content-Type" content="text/html; charset=utf-8"> < title> hello world< /title> < /head> < body> < h1> hello world< /h1> < /body> < /html> 结果:三、来看看AbstractHandlerMethodMapping系列由于AbstractHandlerMethodMapping实现了InitializingBean接口,所以会自动调用afterPropertiesSet方法,这个方法里面直接调用了initHandlerMethods方法 获取handler protected void initHandlerMethods() { if (logger.isDebugEnabled()) { logger.debug("Looking for request mappings in application context: " + getApplicationContext()); } String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ? //获取applicationContext中的所有bean,Obejct类是所有bean的基类 BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) : getApplicationContext().getBeanNamesForType(Object.class)); for (String beanName : beanNames) { if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) { Class< ?> beanType = null; try { //获取对应beanName的Bean的类型 beanType = getApplicationContext().getType(beanName); } catch (Throwable ex) { // An unresolvable bean type, probably from a lazy bean - let‘s ignore it. if (logger.isDebugEnabled()) { logger.debug("Could not resolve target class for bean with name ‘" + beanName + "‘", ex); } } if (beanType != null & & isHandler(beanType)) { detectHandlerMethods(beanName); } } } handlerMethodsInitialized(getHandlerMethods()); }看到isHandler方法:@Override protected boolean isHandler(Class< ?> beanType) { return ((AnnotationUtils.findAnnotation(beanType, Controller.class) != null) || (AnnotationUtils.findAnnotation(beanType, RequestMapping.class) != null)); }只要类上面标注了controller或者requestMapping就属于它能够处理的handler。protected void detectHandlerMethods(final Object handler) { //如果handler是String类型的就从ApplicationContext中获取它的类型,如果不是就直接获取它的类型 Class< ?> handlerType = (handler instanceof String ? getApplicationContext().getType((String) handler) : handler.getClass()); //获取用户的class,如果是Cglib代理类,那么就会获取它的父类class final Class< ?> userType = ClassUtils.getUserClass(handlerType); Map< Method, T> methods = MethodIntrospector.selectMethods(userType, new MethodIntrospector.MetadataLookup< T> () { @Override public T inspect(Method method) { return getMappingForMethod(method, userType); } }); if (logger.isDebugEnabled()) { logger.debug(methods.size() + " request handler methods found on " + userType + ": " + methods); } for (Map.Entry< Method, T> entry : methods.entrySet()) { registerHandlerMethod(handler, entry.getKey(), entry.getValue()); } }MethodIntrospector.selectMethodspublic static < T> Map< Method, T> selectMethods(Class< ?> targetType, final MetadataLookup< T> metadataLookup) { final Map< Method, T> methodMap = new LinkedHashMap< Method, T> (); Set< Class< ?> > handlerTypes = new LinkedHashSet< Class< ?> > (); Class< ?> specificHandlerType = null; //目标类型是否是代理类 if (!Proxy.isProxyClass(targetType)) { handlerTypes.add(targetType); specificHandlerType = targetType; } handlerTypes.addAll(Arrays.asList(targetType.getInterfaces())); for (Class< ?> currentHandlerType : handlerTypes) { final Class< ?> targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType); ReflectionUtils.doWithMethods(currentHandlerType, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) { Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass); T result = metadataLookup.inspect(specificMethod); if (result != null) { Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); if (bridgedMethod == specificMethod || metadataLookup.inspect(bridgedMethod) == null) { methodMap.put(specificMethod, result); } } } }, ReflectionUtils.USER_DECLARED_METHODS); }return methodMap; }ReflectionUtils.doWithMethodspublic static void doWithMethods(Class< ?> clazz, MethodCallback mc, MethodFilter mf) { // Keep backing up the inheritance hierarchy. //获取这个handler类的所有方法,当然也可能是接口的方法 Method[] methods = getDeclaredMethods(clazz); for (Method method : methods) { //mf.matches(method)使用的是传进来的匿名类 if (mf != null & & !mf.matches(method)) { continue; } try { mc.doWith(method); } catch (IllegalAccessException ex) { throw new IllegalStateException("Not allowed to access method ‘" + method.getName() + "‘: " + ex); } } if (clazz.getSuperclass() != null) { doWithMethods(clazz.getSuperclass(), mc, mf); } else if (clazz.isInterface()) { for (Class< ?> superIfc : clazz.getInterfaces()) { doWithMethods(superIfc, mc, mf); } } }//这是doMatch方法中调用的一个方法 public static Method getMostSpecificMethod(Method method, Class< ?> targetClass) { //如果方法不为空,并且是可以重载的,即不是private修饰的, if (method != null & & isOverridable(method, targetClass) & & targetClass != null & & targetClass != method.getDeclaringClass()) { try { if (Modifier.isPublic(method.getModifiers())) { try { return targetClass.getMethod(method.getName(), method.getParameterTypes()); } catch (NoSuchMethodException ex) { return method; } } else { Method specificMethod = ReflectionUtils.findMethod(targetClass, method.getName(), method.getParameterTypes()); return (specificMethod != null ? specificMethod : method); } } catch (SecurityException ex) { // Security settings are disallowing reflective access; fall back to ‘method‘ below. } } return method; }getMappingForMethod(method, userType); @Override protected RequestMappingInfo getMappingForMethod(Method method, Class< ?> handlerType) { RequestMappingInfo info = createRequestMappingInfo(method); if (info != null) { RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType); if (typeInfo != null) { info = typeInfo.combine(info); } } return info; }private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) { //如果当前方法包含RequestMapping注解 RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class); RequestCondition< ?> condition = (element instanceof Class< ?> ? getCustomTypeCondition((Class< ?> ) element) : getCustomMethodCondition((Method) element)); return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null); }如果这个方法有requestMapping注解,那么就创建RequestMappingInfo对象 protected RequestMappingInfo createRequestMappingInfo( RequestMapping requestMapping, RequestCondition< ?> customCondition) {return RequestMappingInfo .paths(resolveEmbeddedValuesInPatterns(requestMapping.path())) .methods(requestMapping.method()) .params(requestMapping.params()) .headers(requestMapping.headers()) .consumes(requestMapping.consumes()) .produces(requestMapping.produces()) .mappingName(requestMapping.name()) .customCondition(customCondition) .options(this.config) .build(); }此方法返回后又回到了 @Override protected RequestMappingInfo getMappingForMethod(Method method, Class< ?> handlerType) { RequestMappingInfo info = createRequestMappingInfo(method); if (info != null) { RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType); if (typeInfo != null) { info = typeInfo.combine(info); } } return info; } 这个方法 如果info 不为空,那么就检测类上面是否有requestMapping注解,如果有也创建一个requestMappingInfo对象,最后进行合并(combine)。 createRequestMappingInfo里面有判断当前方法是否为桥接方法,桥接方法是在泛型中出现的,这是因为编译器在编译时会擦除泛型,比如子类实现带泛型的父类,并且在实现的时候指定了这个泛型的类型,比如public interface Action< T> { public void eat(T t); }public class DogAction implements Action< Dog> { public void eat(Dog t) { System.out.println(""); } }在编译字节码的时候会在DogAction 出现连个方法,一个是擦除泛型的方法 public void eat(Dog t) { System.out.println(""); }另一个是桥接方法 public void eat(Object t) { this.eat((Dog)t); }由于在jdk5以前是没有泛型的,为了能得到兼容,所以就有了桥接方法,在jdk5以前是没有泛型的, 所以以前不管是什么都会当做Object的对象来处理,此时,如果传入了Object类型(实际类型是Dog)的,那么就会调用桥接方法,如果出入一个真实类型为Object的对象,那么在运行的时候就会报错。最后构造methodMap.put(specificMethod, result); 一个用method做为key,用requestMappingInfo做值的Map接下来注册处理器存在HandlerMapping中等待使用 for (Map.Entry< Method, T> entry : methods.entrySet()) { registerHandlerMethod(handler, entry.getKey(), entry.getValue()); }protected void registerHandlerMethod(Object handler, Method method, T mapping) { this.mappingRegistry.register(mapping, handler, method); }public void register(T mapping, Object handler, Method method) { //获取写锁 this.readWriteLock.writeLock().lock(); try { //创建handlerMethod对象 HandlerMethod handlerMethod = createHandlerMethod(handler, method); //判断该handle人Mthod是不是唯一的处理器,如果不是就抛出错误 assertUniqueMethodMapping(handlerMethod, mapping); if (logger.isInfoEnabled()) { logger.info("Mapped "" + mapping + "" onto " + handlerMethod); } //将处理器方法按照requestMappingInfo-》handle人Mthod键值对的方式存入mappingLookup this.mappingLookup.put(mapping, handlerMethod); //获取可以映射到这个requestMappingInfo的url List< String> directUrls = getDirectUrls(mapping); for (String url : directUrls) { //URLLookup是一个继承了Map的容器,不过它的值是一个list this.urlLookup.add(url, mapping); }String name = null; if (getNamingStrategy() != null) { //name-》handlermethod,命名策略使用的类名中大写字母的组合加#和方法名组成的key name = getNamingStrategy().getName(handlerMethod, mapping); //将以name-》handlermethod的方式加入到nameLookup这个map中,一样的值是一个list,这个list存着handlermethod addMappingName(name, handlerMethod); } //初始化跨域配置 CorsConfiguration corsConfig = initCorsConfiguration(handler, method, mapping); if (corsConfig != null) { this.corsLookup.put(handlerMethod, corsConfig); }this.registry.put(mapping, new MappingRegistration< T> (mapping, handlerMethod, directUrls, name)); } finally { this.readWriteLock.writeLock().unlock(); } }//创建handlermethod实例 protected HandlerMethod createHandlerMethod(Object handler, Method method) { HandlerMethod handlerMethod; if (handler instanceof String) { String beanName = (String) handler; handlerMethod = new HandlerMethod(beanName, getApplicationContext().getAutowireCapableBeanFactory(), method); } else { handlerMethod = new HandlerMethod(handler, method); } return handlerMethod; } //handleMthod的构造方法 public HandlerMethod(Object bean, Method method) { Assert.notNull(bean, "Bean is required"); Assert.notNull(method, "Method is required"); this.bean = bean; this.beanFactory = null; this.beanType = ClassUtils.getUserClass(bean); this.method = method; this.bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); this.parameters = initMethodParameters(); this.resolvedFromHandlerMethod = null; }//获取handlerMthod protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception { String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); if (logger.isDebugEnabled()) { logger.debug("Looking up handler method for path " + lookupPath); } this.mappingRegistry.acquireReadLock(); try { HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request); if (logger.isDebugEnabled()) { if (handlerMethod != null) { logger.debug("Returning handler method [" + handlerMethod + "]"); } else { logger.debug("Did not find handler method for [" + lookupPath + "]"); } } return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null); } finally { this.mappingRegistry.releaseReadLock(); } }protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception { //这个match是一个内部类,有两个属性,分别为条件(默认是requestMappingInfo),handlerMethod List< Match> matches = new ArrayList< Match> (); //通过url来查找条件(这里默认是requestMappinginfo) List< T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath); if (directPathMatches != null) { //找到匹配的条件,比如比较他们的请求方法,参数,headers等 addMatchingMappings(directPathMatches, matches, request); } //如果没有找到,那么就直接遍历所有的条件 if (matches.isEmpty()) { // No choice but to go through all mappings... addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request); } //如果不为空,就对进行排序 if (!matches.isEmpty()) { Comparator< Match> comparator = new MatchComparator(getMappingComparator(request)); //排序,排序方法是根据条件进行排序的,其中url的匹配优先级最高 Collections.sort(matches, comparator); if (logger.isTraceEnabled()) { logger.trace("Found " + matches.size() + " matching mapping(s) for [" + lookupPath + "] : " + matches); } //第一个匹配的做为最佳 Match bestMatch = matches.get(0); if (matches.size() > 1) { if (CorsUtils.isPreFlightRequest(request)) { return PREFLIGHT_AMBIGUOUS_MATCH; } Match secondBestMatch = matches.get(1); //对比连个匹配的处理器,如果完全相等,那么就抛出异常 if (comparator.compare(bestMatch, secondBestMatch) == 0) { Method m1 = bestMatch.handlerMethod.getMethod(); Method m2 = secondBestMatch.handlerMethod.getMethod(); throw new IllegalStateException("Ambiguous handler methods mapped for HTTP path ‘" + request.getRequestURL() + "‘: {" + m1 + ", " + m2 + "}"); } } //重新封装成handlermethod handleMatch(bestMatch.mapping, lookupPath, request); //返回新的处理器方法 return bestMatch.handlerMethod; } else { return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request); } }获取到handler以后返回到 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); } //获取到handlerExecutionChain HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); 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; }protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? (HandlerExecutionChain) handler : new HandlerExecutionChain(handler)); //通过url找到需要拦截的拦截器 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; }得到HandlerExecutionChain 后回到doDispatcher()方法HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { for (HandlerAdapter ha : this.handlerAdapters) { if (logger.isTraceEnabled()) { logger.trace("Testing handler adapter [" + ha + "]"); } if (ha.supports(handler)) { return ha; } } throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }找打匹配的适配器 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {ModelAndView mav; //检查request的请求方法是否是允许的 checkRequest(request); // Execute invokeHandlerMethod in synchronized block if required. if (this.synchronizeOnSession) { HttpSession session = request.getSession(false); if (session != null) { Object mutex = WebUtils.getSessionMutex(session); synchronized (mutex) { mav = invokeHandlerMethod(request, response, handlerMethod); } } else { // No HttpSession available -> no mutex necessary mav = invokeHandlerMethod(request, response, handlerMethod); } } else { // No synchronization on session demanded at all... mav = invokeHandlerMethod(request, response, handlerMethod); }if (!response.containsHeader(HEADER_CACHE_CONTROL)) { if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) { applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers); } else { prepareResponse(response); } }return mav; }

【handlerMapping的初始化以及查找handler】 


    推荐阅读