深入理解Collections的unmodifiableMap(Map map)方法: http://donald-draper.iteye.com/blog/2326291
Spring-RequestMappingHandlerAdapter初始化及请求处理: http://donald-draper.iteye.com/blog/2326185
我们来看DispatcherServlet的handlerMappings初始化所做的事情
public class DispatcherServlet extends FrameworkServlet { public DispatcherServlet(WebApplicationContext webApplicationContext) { super(webApplicationContext); detectAllHandlerMappings = true; detectAllHandlerAdapters = true; detectAllHandlerExceptionResolvers = true; detectAllViewResolvers = true; throwExceptionIfNoHandlerFound = false; cleanupAfterInclude = true; } //初始化控制器映射 private void initHandlerMappings(ApplicationContext context) { handlerMappings = null; if(detectAllHandlerMappings) { Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, org/springframework/web/servlet/HandlerMapping, true, false); if(!matchingBeans.isEmpty()) { //List<HashMap<String,HandlerMapping>>,Key为beanName,value值为HandlerMapping实例 handlerMappings = new ArrayList(matchingBeans.values()); OrderComparator.sort(handlerMappings); } } } //初始化控制器方法适配器 private void initHandlerAdapters(ApplicationContext context) { handlerAdapters = null; if(detectAllHandlerAdapters) { Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, org/springframework/web/servlet/HandlerAdapter, true, false); if(!matchingBeans.isEmpty()) { //List<HashMap<String,HandlerAdapter>>,Key为beanName,value值为HandlerAdapter实例 handlerAdapters = new ArrayList(matchingBeans.values()); OrderComparator.sort(handlerAdapters); } } } private List handlerMappings;//List<HashMap<String,HandlerMapping>>,Key为beanName,value值为HandlerMapping实例 private List handlerAdapters;//List<HashMap<String,HandlerAdapter>>,Key为beanName,value值为HandlerAdapter实例 private List handlerExceptionResolvers; private List viewResolvers; static { try { //加载默认配置文件 ClassPathResource resource = new ClassPathResource("DispatcherServlet.properties", org/springframework/web/servlet/DispatcherServlet); defaultStrategies = PropertiesLoaderUtils.loadProperties(resource); } } }
//Spring日志追踪我们可以发现,DispatcherServletd的控制器映射处理器为
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
这里我们来看RequestMappingHandlerMapping
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping implements EmbeddedValueResolverAware { //初始化 public void afterPropertiesSet() { if(useRegisteredSuffixPatternMatch) fileExtensions.addAll(contentNegotiationManager.getAllFileExtensions()); //调用父类的初始化 super.afterPropertiesSet(); } private boolean useSuffixPatternMatch; private boolean useRegisteredSuffixPatternMatch; private boolean useTrailingSlashMatch; private ContentNegotiationManager contentNegotiationManager; private final List fileExtensions = new ArrayList(); private StringValueResolver embeddedValueResolver; } 来查看AbstractHandlerMethodMapping public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMapping implements InitializingBean { //初始化 public void afterPropertiesSet() { //委托给initHandlerMethods initHandlerMethods(); } //初始化方法处理器 protected void initHandlerMethods() { //获取所有bean容器的beanName String beanNames[] = detectHandlerMethodsInAncestorContexts ? BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), java/lang/Object) : getApplicationContext().getBeanNamesForType(java/lang/Object); String as[] = beanNames; int i = as.length; for(int j = 0; j < i; j++) { String beanName = as[j]; //如果bean为Controller if(!beanName.startsWith("scopedTarget.") && isHandler(getApplicationContext().getType(beanName))) // detectHandlerMethods(beanName); } handlerMethodsInitialized(getHandlerMethods()); } //获取方法处理器Map public Map getHandlerMethods() { //返回一个不可修改的Map集 return Collections.unmodifiableMap(handlerMethods); } //留给子类扩展 protected void handlerMethodsInitialized(Map map) { } //委托给RequestMappingHandlerMapping protected abstract boolean isHandler(Class class1); //将handler带@RequestMapping的方法添加到方法处理器Map中handlerMethods,及路径映射Map中urlMap protected void detectHandlerMethods(Object handler) { Class handlerType = (handler instanceof String) ? getApplicationContext().getType((String)handler) : handler.getClass(); //注意这里用的是IdentityHashMap final Map mappings = new IdentityHashMap(); final Class userType = ClassUtils.getUserClass(handlerType); //获取Contoller所有带@RequestMapping的方法 Set methods = HandlerMethodSelector.selectMethods(userType, new org.springframework.util.ReflectionUtils.MethodFilter() { public boolean matches(Method method) { //获取handlerType的method的@RequestMapping注解信息 Object mapping = getMappingForMethod(method, userType); if(mapping != null) { mappings.put(method, mapping); return true; } else { return false; } } final Class val$userType; final Map val$mappings; final AbstractHandlerMethodMapping this$0; { this.this$0 = AbstractHandlerMethodMapping.this; userType = class1; mappings = map; super(); } }); Method method; for(Iterator iterator = methods.iterator(); iterator.hasNext(); registerHandlerMethod(handler, method, mappings.get(method))) method = (Method)iterator.next(); } protected void registerHandlerMethod(Object handler, Method method, Object mapping) { //创建方法处理器 HandlerMethod newHandlerMethod = createHandlerMethod(handler, method); //从handlerMethods中获取方法处理器信息根据@RequestMapping注解信息 HandlerMethod oldHandlerMethod = (HandlerMethod)handlerMethods.get(mapping); //如果已经存在,则抛出不能映射异常 if(oldHandlerMethod != null && !oldHandlerMethod.equals(newHandlerMethod)) throw new IllegalStateException((new StringBuilder()).append("Ambiguous mapping found. Cannot map '").append(newHandlerMethod.getBean()).append("' bean method \n").append(newHandlerMethod).append("\nto ").append(mapping).append(": There is already '").append(oldHandlerMethod.getBean()).append("' bean method\n").append(oldHandlerMethod).append(" mapped.").toString()); //将方法处理器放入handlerMethods中 handlerMethods.put(mapping, newHandlerMethod); if(logger.isInfoEnabled()) logger.info((new StringBuilder()).append("Mapped \"").append(mapping).append("\" onto ").append(newHandlerMethod).toString()); //获取路径集 Set patterns = getMappingPathPatterns(mapping); Iterator iterator = patterns.iterator(); do { if(!iterator.hasNext()) break; String pattern = (String)iterator.next(); if(!getPathMatcher().isPattern(pattern)) //将路径与mapping关联 urlMap.add(pattern, mapping); } while(true); } //委托给RequestMappingInfoHandlerMapping protected abstract Object getMappingForMethod(Method method, Class class1); protected abstract Set getMappingPathPatterns(Object obj); //根据request的url寻找合适的HandlerMethod protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception { String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); if(logger.isDebugEnabled()) logger.debug((new StringBuilder()).append("Looking up handler method for path ").append(lookupPath).toString()); //根据路径和request寻找handlerMethod HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request); if(logger.isDebugEnabled()) if(handlerMethod != null) logger.debug((new StringBuilder()).append("Returning handler method [").append(handlerMethod).append("]").toString()); else logger.debug((new StringBuilder()).append("Did not find handler method for [").append(lookupPath).append("]").toString()); return handlerMethod == null ? null : handlerMethod.createWithResolvedBean(); } //根据路径和request寻找handlerMethod protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception { List matches = new ArrayList(); List directPathMatches = (List)urlMap.get(lookupPath); if(directPathMatches != null) addMatchingMappings(directPathMatches, matches, request); if(matches.isEmpty()) addMatchingMappings(handlerMethods.keySet(), matches, request); if(!matches.isEmpty()) { Comparator comparator = new MatchComparator(getMappingComparator(request)); Collections.sort(matches, comparator); if(logger.isTraceEnabled()) logger.trace((new StringBuilder()).append("Found ").append(matches.size()).append(" matching mapping(s) for [").append(lookupPath).append("] : ").append(matches).toString()); Match bestMatch = (Match)matches.get(0); if(matches.size() > 1) { Match secondBestMatch = (Match)matches.get(1); if(comparator.compare(bestMatch, secondBestMatch) == 0) { Method m1 = bestMatch.handlerMethod.getMethod(); Method m2 = secondBestMatch.handlerMethod.getMethod(); throw new IllegalStateException((new StringBuilder()).append("Ambiguous handler methods mapped for HTTP path '").append(request.getRequestURL()).append("': {").append(m1).append(", ").append(m2).append("}").toString()); } } handleMatch(bestMatch.mapping, lookupPath, request); return bestMatch.handlerMethod; } else { return handleNoMatch(handlerMethods.keySet(), lookupPath, request); } } private static final String SCOPED_TARGET_NAME_PREFIX = "scopedTarget."; private boolean detectHandlerMethodsInAncestorContexts; //LinkedHashMap<RequestMappingInfo,HandlerMethod> private final Map handlerMethods = new LinkedHashMap(); /LinkedHashMap<String,RequestMappingInfo>,key为路径 private final MultiValueMap urlMap = new LinkedMultiValueMap(); }
查看RequestMappingHandlerMapping.isHandler()
//isHandler,判断bean是否带有@Controller
protected boolean isHandler(Class beanType) { return AnnotationUtils.findAnnotation(beanType, org/springframework/stereotype/Controller) != null || AnnotationUtils.findAnnotation(beanType, org/springframework/web/bind/annotation/RequestMapping) != null; }
查看RequestMappingHandlerMapping.getMappingForMethod()
protected volatile Object getMappingForMethod(Method method, Class class1) { return getMappingForMethod(method, class1); }
//判断handlerType的method是否带@RequestMapping,并返回注解信息
protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) { RequestMappingInfo info = null; RequestMapping methodAnnotation = (RequestMapping)AnnotationUtils.findAnnotation(method, org/springframework/web/bind/annotation/RequestMapping); if(methodAnnotation != null) { RequestCondition methodCondition = getCustomMethodCondition(method); info = createRequestMappingInfo(methodAnnotation, methodCondition); RequestMapping typeAnnotation = (RequestMapping)AnnotationUtils.findAnnotation(handlerType, org/springframework/web/bind/annotation/RequestMapping); if(typeAnnotation != null) { RequestCondition typeCondition = getCustomTypeCondition(handlerType); info = createRequestMappingInfo(typeAnnotation, typeCondition).combine(info); } } return info; }
查看RequestMappingInfoHandlerMapping.getMappingPathPatterns()
public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMethodMapping { protected Set getMappingPathPatterns(RequestMappingInfo info) { return info.getPatternsCondition().getPatterns(); } }
//RequestMappingInfo
public final class RequestMappingInfo implements RequestCondition { public PatternsRequestCondition getPatternsCondition() { return patternsCondition; } private final PatternsRequestCondition patternsCondition; private final RequestMethodsRequestCondition methodsCondition; private final ParamsRequestCondition paramsCondition; private final HeadersRequestCondition headersCondition; private final ConsumesRequestCondition consumesCondition; private final ProducesRequestCondition producesCondition; private final RequestConditionHolder customConditionHolder; }
查看PatternsRequestCondition
public final class PatternsRequestCondition extends AbstractRequestCondition { public Set getPatterns() { return patterns; } private final Set patterns; private final UrlPathHelper pathHelper; private final PathMatcher pathMatcher; private final boolean useSuffixPatternMatch; private final boolean useTrailingSlashMatch; private final List fileExtensions; }
//RequestMappingInfo
public final class RequestMappingInfo implements RequestCondition { public PatternsRequestCondition getPatternsCondition() { return patternsCondition; } private final PatternsRequestCondition patternsCondition; private final RequestMethodsRequestCondition methodsCondition; private final ParamsRequestCondition paramsCondition; private final HeadersRequestCondition headersCondition; private final ConsumesRequestCondition consumesCondition; private final ProducesRequestCondition producesCondition; private final RequestConditionHolder customConditionHolder; }
查看PatternsRequestCondition
public final class PatternsRequestCondition extends AbstractRequestCondition { public Set getPatterns() { return patterns; } private final Set patterns; private final UrlPathHelper pathHelper; private final PathMatcher pathMatcher; private final boolean useSuffixPatternMatch; private final boolean useTrailingSlashMatch; private final List fileExtensions; }
//HandlerMethod public class HandlerMethod { public HandlerMethod(Object bean, Method method) { this.bean = bean; beanFactory = null; this.method = method; bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); parameters = initMethodParameters(); } public transient HandlerMethod(Object bean, String methodName, Class parameterTypes[]) throws NoSuchMethodException { this.bean = bean; beanFactory = null; method = bean.getClass().getMethod(methodName, parameterTypes); bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); parameters = initMethodParameters(); } public HandlerMethod(String beanName, BeanFactory beanFactory, Method method) { bean = beanName; this.beanFactory = beanFactory; this.method = method; bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); parameters = initMethodParameters(); } protected HandlerMethod(HandlerMethod handlerMethod) { bean = handlerMethod.bean; beanFactory = handlerMethod.beanFactory; method = handlerMethod.method; bridgedMethod = handlerMethod.bridgedMethod; parameters = handlerMethod.parameters; } private HandlerMethod(HandlerMethod handlerMethod, Object handler) { bean = handler; beanFactory = handlerMethod.beanFactory; method = handlerMethod.method; bridgedMethod = handlerMethod.bridgedMethod; parameters = handlerMethod.parameters; } private final Object bean; private final BeanFactory beanFactory; private final Method method; private final Method bridgedMethod; private final MethodParameter parameters[]; }
总结:
从以上分析,可以看出RequestMappingHandlerMapping,主要做的工作是将Contoller的带RequestMapping方法,添加到处理方法映射器和路径方法解决器中。