spring mvc HanderMapping源码

https://my.oschina.net/zhangxufeng/blog/2177464

spring mvc HanderMapping源码

RequestMappingHandlerMapping getMappingForMethod



    /**
     * {@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注解的方法注册一下  handlerMethods  urlMap     RequestMappingInfo 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 method        RequestMappingInfo 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);
            }
        }
    }

RequestMappingInfoHandlerMapping


    /**
     * Get the URL path patterns associated with this {@link RequestMappingInfo}.
     */
    @Override
    protected Set<String> getMappingPathPatterns(RequestMappingInfo info) {
        return info.getPatternsCondition().getPatterns();
    }

spring mvc HanderMapping源码

上一篇:运行流畅快速不卡顿的第三方Android模拟器的安装及配置——夜神模拟器


下一篇:史上最简单的个人移动APP开发入门--jQuery Mobile版跨平台APP开发