spring mvc HanderMapping源码

家资是何物,积帙列梁梠。这篇文章主要讲述spring mvc HanderMapping源码相关的知识,希望能为你提供帮助。
https://my.oschina.net/zhangxufeng/blog/2177464

spring mvc HanderMapping源码

文章图片

RequestMappingHandlerMappinggetMappingForMethod
/** * {@inheritDoc} * Expects a handler to have a type-level @{@link Controller} annotation. */ @Override protected boolean isHandler(Class< ?> beanType) { return AnnotationUtils.findAnnotation(beanType, Controller.class) != null; } /** * Uses method and type-level @{@link RequestMapping} annotations to create * the RequestMappingInfo. * * @return the created RequestMappingInfo, or {@code null} if the method * does not have a {@code @RequestMapping} annotation. * * @see #getCustomMethodCondition(Method) * @see #getCustomTypeCondition(Class) */ @Override protected RequestMappingInfo getMappingForMethod(Method method, Class< ?> handlerType) { RequestMappingInfo info = null; RequestMapping methodAnnotation = AnnotationUtils.findAnnotation(method, RequestMapping.class); if (methodAnnotation != null) { RequestCondition< ?> methodCondition = getCustomMethodCondition(method); info = createRequestMappingInfo(methodAnnotation, methodCondition); RequestMapping typeAnnotation = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class); if (typeAnnotation != null) { RequestCondition< ?> typeCondition = getCustomTypeCondition(handlerType); info = createRequestMappingInfo(typeAnnotation, typeCondition).combine(info); } } return info; }

AbstractHandlerMethodMapping
/** * ApplicationContext initialization and handler method detection. */ @Override public void initApplicationContext() throws ApplicationContextException { super.initApplicationContext(); initHandlerMethods(); } /** * Scan beans in the ApplicationContext, detect and register handler methods. * @see #isHandler(Class) * @see #getMappingForMethod(Method, Class) * @see #handlerMethodsInitialized(Map) */ protected void initHandlerMethods() { if (logger.isDebugEnabled()) { logger.debug("Looking for request mappings in application context: " + getApplicationContext()); }String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ? BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) : getApplicationContext().getBeanNamesForType(Object.class)); for (String beanName : beanNames) { // 判断类上面是否有Controller 注解 如果有则查找它及它的方法是否有RequestMapping注解 if (isHandler(getApplicationContext().getType(beanName))){ detectHandlerMethods(beanName); } } handlerMethodsInitialized(getHandlerMethods()); } /** * Look for handler methods in a handler. * @param handler the bean name of a handler or a handler instance */ protected void detectHandlerMethods(final Object handler) { Class< ?> handlerType = (handler instanceof String) ? getApplicationContext().getType((String) handler) : handler.getClass(); final Class< ?> userType = ClassUtils.getUserClass(handlerType); //把此类的方法里有RequestMapping注解的方法都找出来 Set< Method> methods = HandlerMethodSelector.selectMethods(userType, new MethodFilter() { public boolean matches(Method method) { return getMappingForMethod(method, userType) != null; } }); //将有RequestMapping注解的方法注册一下handlerMethodsurlMapRequestMappingInfo mapping for (Method method : methods) { T mapping = getMappingForMethod(method, userType); registerHandlerMethod(handler, method, mapping); } } /** * Provide the mapping for a handler method. A method for which no * mapping can be provided is not a handler method. * * @param method the method to provide a mapping for * @param handlerType the handler type, possibly a sub-type of the method\'s * declaring class * @return the mapping, or {@code null} if the method is not mapped */ protected abstract T getMappingForMethod(Method method, Class< ?> handlerType); /** * Register a handler method and its unique mapping. * * @param handler the bean name of the handler or the handler instance * @param method the method to register * @param mapping the mapping conditions associated with the handler methodRequestMappingInfo mapping * @throws IllegalStateException if another method was already registered * under the same mapping */ protected void registerHandlerMethod(Object handler, Method method, T mapping) { HandlerMethod handlerMethod; if (handler instanceof String) { String beanName = (String) handler; handlerMethod = new HandlerMethod(beanName, getApplicationContext(), method); } else { handlerMethod = new HandlerMethod(handler, method); }HandlerMethod oldHandlerMethod = handlerMethods.get(mapping); if (oldHandlerMethod != null & & !oldHandlerMethod.equals(handlerMethod)) { throw new IllegalStateException("Ambiguous mapping found. Cannot map \'" + handlerMethod.getBean() + "\' bean method \\n" + handlerMethod + "\\nto " + mapping + ": There is already \'" + oldHandlerMethod.getBean() + "\' bean method\\n" + oldHandlerMethod + " mapped."); }handlerMethods.put(mapping, handlerMethod); if (logger.isInfoEnabled()) { logger.info("Mapped \\"" + mapping + "\\" onto " + handlerMethod); }Set< String> patterns = getMappingPathPatterns(mapping); for (String pattern : patterns) { if (!getPathMatcher().isPattern(pattern)) { urlMap.add(pattern, mapping); } } }

【spring mvc HanderMapping源码】RequestMappingInfoHandlerMapping
/** * Get the URL path patterns associated with this {@link RequestMappingInfo}. */ @Override protected Set< String> getMappingPathPatterns(RequestMappingInfo info) { return info.getPatternsCondition().getPatterns(); }


    推荐阅读