handlerMapping的初始化以及查找handler
Posted zhenhong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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中寻找,加入我们自定义一个借口叫做IController package com.booway.custominterface; import org.springframework.web.servlet.ModelAndView; public interface IController { public ModelAndView IHandlerRequest() throws Exception; } 定义一个HandlerMapping package 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; } } 定义一个controller package 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="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.selectMethods public 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.doWithMethods public 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; }