RequestMappingHandlerAdapter的初始化原理

文章详细描述了SpringMVC中`ControllerRequestMappingHandlerAdapter`的初始化过程,重点涉及如何查找并初始化带有@ControllerAdvice注解的类,以及如何配置参数解析器和返回值处理器,包括RequestParam、ModelAttribute等注解的处理。
class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter implements InitializingBean {
    public void afterPropertiesSet() {
        // 初始化被@ControllerAdvice标注的类
        initControllerAdviceCache();{
            List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());{
                // 保存添加了@ControllerAdvice注解的类信息
                List<ControllerAdviceBean> adviceBeans = new ArrayList<>();
                // 找到所有的beanName
                String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Object.class);
                for (String name : beanNames) {
                    // 判断是否是代理的Bean,添加了@Scoped的标识,添加了返回true
                    if (!ScopedProxyUtils.isScopedTarget(name)) {
                        // 找到Bean中带有@ControllerAdvice的类
                        ControllerAdvice controllerAdvice = beanFactory.findAnnotationOnBean(name, ControllerAdvice.class);
                        if (controllerAdvice != null) {
                            // 将这些信息包装成ControllerAdviceBean对象,避免后续再次找相同的Bean
                            adviceBeans.add(new ControllerAdviceBean(name, beanFactory, controllerAdvice));
                        }
                    }
                }
                // 对这些bean进行排序
                OrderComparator.sort(adviceBeans);
                return adviceBeans;
            }
            List<Object> requestResponseBodyAdviceBeans = new ArrayList<>();
            Class<?> beanType = adviceBean.getBeanType();
            // 获取Bean中带有的ModelAttribute的注解,但不能有RequestMapping
            // public static final MethodFilter MODEL_ATTRIBUTE_METHODS = method -> {
            //  			!AnnotatedElementUtils.hasAnnotation(method, RequestMapping.class) &&
            //  			AnnotatedElementUtils.hasAnnotation(method, ModelAttribute.class));
            Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
            if (!attrMethods.isEmpty()) {
                // 找到了就先缓存起来modelAttributeAdviceCache,防止之后再扫描
                this.modelAttributeAdviceCache.put(adviceBean, attrMethods);
            }
            // 获取Bean中带有的InitBinder的注解
            // public static final MethodFilter INIT_BINDER_METHODS = method ->
            //			AnnotatedElementUtils.hasAnnotation(method, InitBinder.class);
            Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
            if (!binderMethods.isEmpty()) {
                // 找到了就先缓存起来initBinderAdviceCache,防止之后再扫描
                this.initBinderAdviceCache.put(adviceBean, binderMethods);
            }
            // 如果bean的类型是RequestBodyAdvice或者ResponseBodyAdvice
            if (RequestBodyAdvice.class.isAssignableFrom(beanType) || ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
                // 保存到本地变量requestResponseBodyAdviceBeans中
                requestResponseBodyAdviceBeans.add(adviceBean);
            }
        }
        // 如果找到了RequestBodyAdvice或者ResponseBodyAdvice
        if (!requestResponseBodyAdviceBeans.isEmpty()) {
            // 缓存起来,防止之后再扫描
            this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);
        }
    }
    // 是否有参数解析器,如果没有设置
    if (this.argumentResolvers == null) {
        // 获取默认的参数解析器
        List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();{
            List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(30);

            // 解析注解参数的解析器
            resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
            resolvers.add(new RequestParamMapMethodArgumentResolver());
            resolvers.add(new PathVariableMethodArgumentResolver());
            resolvers.add(new PathVariableMapMethodArgumentResolver());
            resolvers.add(new MatrixVariableMethodArgumentResolver());
            resolvers.add(new MatrixVariableMapMethodArgumentResolver());
            resolvers.add(new ServletModelAttributeMethodProcessor(false));
            resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
            resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
            resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
            resolvers.add(new RequestHeaderMapMethodArgumentResolver());
            resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
            resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
            resolvers.add(new SessionAttributeMethodArgumentResolver());
            resolvers.add(new RequestAttributeMethodArgumentResolver());

            // 解析特殊类型的解析器
            resolvers.add(new ServletRequestMethodArgumentResolver());
            resolvers.add(new ServletResponseMethodArgumentResolver());
            resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
            resolvers.add(new RedirectAttributesMethodArgumentResolver());
            resolvers.add(new ModelMethodProcessor());
            resolvers.add(new MapMethodProcessor());
            resolvers.add(new ErrorsMethodArgumentResolver());
            resolvers.add(new SessionStatusMethodArgumentResolver());
            resolvers.add(new UriComponentsBuilderMethodArgumentResolver());
            if (KotlinDetector.isKotlinPresent()) {
                resolvers.add(new ContinuationHandlerMethodArgumentResolver());
            }

            // 自定义参数解析器
            if (getCustomArgumentResolvers() != null) {
                resolvers.addAll(getCustomArgumentResolvers());
            }

            // 剩下其他类型的参数解析器
            resolvers.add(new PrincipalMethodArgumentResolver());
            // 后面这个参数为true,是处理参数不包含RequestParam,但是又是基础类型的参数
            // Enum.class CharSequence.class Number.class Date.class
            // Temporal.class URI.class URL.class Locale.class Class.class
            // 还有八大基本类型
            resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
            resolvers.add(new ServletModelAttributeMethodProcessor(true));

            return resolvers;
        }
        // 将所有的参数解析器保存到HandlerMethodArgumentResolverComposite类中,同时保存到argumentResolvers变量中
        this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
    }
    // 判断是否有initBinder的参数解析器
    if (this.initBinderArgumentResolvers == null) {
        // 获取默认的参数解析器,和
        List<HandlerMethodArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();{
            List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(20);
            resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
            resolvers.add(new RequestParamMapMethodArgumentResolver());
            resolvers.add(new PathVariableMethodArgumentResolver());
            resolvers.add(new PathVariableMapMethodArgumentResolver());
            resolvers.add(new MatrixVariableMethodArgumentResolver());
            resolvers.add(new MatrixVariableMapMethodArgumentResolver());
            resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
            resolvers.add(new SessionAttributeMethodArgumentResolver());
            resolvers.add(new RequestAttributeMethodArgumentResolver());
            resolvers.add(new ServletRequestMethodArgumentResolver());
            resolvers.add(new ServletResponseMethodArgumentResolver());
            if (getCustomArgumentResolvers() != null) {
                resolvers.addAll(getCustomArgumentResolvers());
            }
            resolvers.add(new PrincipalMethodArgumentResolver());
            resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
            return resolvers;
        }
        // 将所有的参数解析器保存到HandlerMethodArgumentResolverComposite类中,同时保存到initBinderArgumentResolvers变量中
        this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
    }
    // 判断是否有返回值处理器
    if (this.returnValueHandlers == null) {
        // 获取默认的返回值处理器
        List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();{
            List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>(20);
            // 处理某个用途的返回值类型
            handlers.add(new ModelAndViewMethodReturnValueHandler());
            handlers.add(new ModelMethodProcessor());
            handlers.add(new ViewMethodReturnValueHandler());
            handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters(),
                    this.reactiveAdapterRegistry, this.taskExecutor, this.contentNegotiationManager));
            handlers.add(new StreamingResponseBodyReturnValueHandler());
            handlers.add(new HttpEntityMethodProcessor(getMessageConverters(),
                    this.contentNegotiationManager, this.requestResponseBodyAdvice));
            handlers.add(new HttpHeadersReturnValueHandler());
            handlers.add(new CallableMethodReturnValueHandler());
            handlers.add(new DeferredResultMethodReturnValueHandler());
            handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));

            // 处理标注了注解的返回值处理器,例如@ModelAttribute,@ResponseBody
            handlers.add(new ServletModelAttributeMethodProcessor(false));
            handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),
                    this.contentNegotiationManager, this.requestResponseBodyAdvice));

            // 处理多用途的返回值类型
            handlers.add(new ViewNameMethodReturnValueHandler());
            handlers.add(new MapMethodProcessor());

            // 自定义的返回值处理器
            if (getCustomReturnValueHandlers() != null) {
                handlers.addAll(getCustomReturnValueHandlers());
            }

            // 处理剩下的返回值处理器
            if (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {
                handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));
            }else{
                handlers.add(new ServletModelAttributeMethodProcessor(true));
            }
            return handlers;
        }
        // 将所有的参数解析器保存到HandlerMethodArgumentResolverComposite类中,同时保存到returnValueHandlers变量中
        this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值