• SpringMVC源码阅读HandlerAdapter初始化-RequestMappingHandlerAdapter(七)


    接口

        public interface HandlerAdapter {
            /**
             * 是否能处理指定Handler
             * @param var1
             * @return
             */
            boolean supports(Object var1);
    
            /**
             * 处理Handler
             * @param var1
             * @param var2
             * @param var3
             * @return
             * @throws Exception
             */
            @Nullable
            ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
    
            /**
             * 获取资源最后一次更新时间
             * @param var1
             * @param var2
             * @return
             */
            long getLastModified(HttpServletRequest var1, Object var2);
        }

    类图

     我们注解方式 都是走RequestMappingHandlerAdapter 

    RequestMappingHandlerAdapter

    afterPropertiesSet

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#afterPropertiesSet

    public void afterPropertiesSet() {
            //<1>对打上了@ControllerAdvice的注解进行加载
            this.initControllerAdviceCache();
            List handlers;
            if (this.argumentResolvers == null) {
                //<2>初始化参数绑定器
                handlers = this.getDefaultArgumentResolvers();
                this.argumentResolvers = (new HandlerMethodArgumentResolverComposite()).addResolvers(handlers);
            }
    
            if (this.initBinderArgumentResolvers == null) {
                //<3>暂时不造干嘛
                handlers = this.getDefaultInitBinderArgumentResolvers();
                this.initBinderArgumentResolvers = (new HandlerMethodArgumentResolverComposite()).addResolvers(handlers);
            }
    
            if (this.returnValueHandlers == null) {
                //<4>初始化响应值处理器
                handlers = this.getDefaultReturnValueHandlers();
                this.returnValueHandlers = (new HandlerMethodReturnValueHandlerComposite()).addHandlers(handlers);
            }
    
        }

    RequestMappingHandlerAdapter

    <1>initControllerAdviceCache

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#afterPropertiesSet

    ->

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#initControllerAdviceCache

     private void initControllerAdviceCache() {
            //判断spring容器是否为空 正常都不会为空
            if (this.getApplicationContext() != null) {
                /**
                 * 扫描如有bean返回打上了@ControllerAdvice的Controlle 封装成ControllerAdviceBean返回
                 * @ControllerAdvice可以做全局异常 全局绑定处理 具体百度搜关键字
                 */
                List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(this.getApplicationContext());
                /**
                 * 如果根据@Order注解排序
                 */
                AnnotationAwareOrderComparator.sort(adviceBeans);
                List<Object> requestResponseBodyAdviceBeans = new ArrayList();
                Iterator var3 = adviceBeans.iterator();
                while(var3.hasNext()) {
                    ControllerAdviceBean adviceBean = (ControllerAdviceBean)var3.next();
                    Class<?> beanType = adviceBean.getBeanType();
                    if (beanType == null) {
                        throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
                    }
                    /**
                     * 找到所有打上了@ModelAttribute的方法 并加入到modelAttributeAdviceCache
                     * 执行所有方法之前都会先执行打上了@ModelAttribute的方法
                     * 具体使用方法可以百度关键字
                     *
                     */
                    Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
                    if (!attrMethods.isEmpty()) {
                        this.modelAttributeAdviceCache.put(adviceBean, attrMethods);
                    }
                    /**
                     * 找到所有打上了了@InitBind方法
                     * 执行参数绑定之前都会先调用@IinitBind 进行自定义绑定器绑定
                     * 具体使用可以百度关键字
                     */
                    Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
                    if (!binderMethods.isEmpty()) {
                        this.initBinderAdviceCache.put(adviceBean, binderMethods);
                    }
    
                    /**
                     * 是否是实现了RequestBodyAdvice接口
                     * 可以统一返回结果之前做自定义处理 比如加响应公参 比如 我业务中需求,增加在响应统一加上traceId
                     */
                    if (RequestBodyAdvice.class.isAssignableFrom(beanType)) {
                        requestResponseBodyAdviceBeans.add(adviceBean);
                    }
    
                    if (ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
                        requestResponseBodyAdviceBeans.add(adviceBean);
                    }
                }
    
                /**
                 * 将requestResponseBodyAdviceBeans 加入到requestResponseBodyAdvice
                 */
                if (!requestResponseBodyAdviceBeans.isEmpty()) {
                    this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);
                }
    
                if (this.logger.isDebugEnabled()) {
                    int modelSize = this.modelAttributeAdviceCache.size();
                    int binderSize = this.initBinderAdviceCache.size();
                    int reqCount = this.getBodyAdviceCount(RequestBodyAdvice.class);
                    int resCount = this.getBodyAdviceCount(ResponseBodyAdvice.class);
                    if (modelSize == 0 && binderSize == 0 && reqCount == 0 && resCount == 0) {
                        this.logger.debug("ControllerAdvice beans: none");
                    } else {
                        this.logger.debug("ControllerAdvice beans: " + modelSize + " @ModelAttribute, " + binderSize + " @InitBinder, " + reqCount + " RequestBodyAdvice, " + resCount + ", ResponseBodyAdvice");
                    }
                }
    
            }
        }

    <2>getDefaultArgumentResolvers

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#afterPropertiesSet

    ->

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDefaultArgumentResolvers

     private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
            List<HandlerMethodArgumentResolver> resolvers = new ArrayList();
            resolvers.add(new RequestParamMethodArgumentResolver(this.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(this.getMessageConverters(), this.requestResponseBodyAdvice));
            resolvers.add(new RequestPartMethodArgumentResolver(this.getMessageConverters(), this.requestResponseBodyAdvice));
            resolvers.add(new RequestHeaderMethodArgumentResolver(this.getBeanFactory()));
            resolvers.add(new RequestHeaderMapMethodArgumentResolver());
            resolvers.add(new ServletCookieValueMethodArgumentResolver(this.getBeanFactory()));
            resolvers.add(new ExpressionValueMethodArgumentResolver(this.getBeanFactory()));
            resolvers.add(new SessionAttributeMethodArgumentResolver());
            resolvers.add(new RequestAttributeMethodArgumentResolver());
            resolvers.add(new ServletRequestMethodArgumentResolver());
            resolvers.add(new ServletResponseMethodArgumentResolver());
            resolvers.add(new HttpEntityMethodProcessor(this.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 (this.getCustomArgumentResolvers() != null) {
                resolvers.addAll(this.getCustomArgumentResolvers());
            }
    
            resolvers.add(new RequestParamMethodArgumentResolver(this.getBeanFactory(), true));
            resolvers.add(new ServletModelAttributeMethodProcessor(true));
            return resolvers;
        }

    <3>getDefaultInitBinderArgumentResolvers

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#afterPropertiesSet

    ->

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDefaultInitBinderArgumentResolvers

     private List<HandlerMethodArgumentResolver> getDefaultInitBinderArgumentResolvers() {
            List<HandlerMethodArgumentResolver> resolvers = new ArrayList();
            resolvers.add(new RequestParamMethodArgumentResolver(this.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(this.getBeanFactory()));
            resolvers.add(new SessionAttributeMethodArgumentResolver());
            resolvers.add(new RequestAttributeMethodArgumentResolver());
            resolvers.add(new ServletRequestMethodArgumentResolver());
            resolvers.add(new ServletResponseMethodArgumentResolver());
            //加入我们自定义的绑定器
            if (this.getCustomArgumentResolvers() != null) {
                resolvers.addAll(this.getCustomArgumentResolvers());
            }
    
            resolvers.add(new RequestParamMethodArgumentResolver(this.getBeanFactory(), true));
            return resolvers;
        }

    <4>getDefaultReturnValueHandlers

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#afterPropertiesSet

    ->

    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDefaultReturnValueHandlers

      private List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {
            List<HandlerMethodReturnValueHandler> handlers = new ArrayList();
            handlers.add(new ModelAndViewMethodReturnValueHandler());
            handlers.add(new ModelMethodProcessor());
            handlers.add(new ViewMethodReturnValueHandler());
            handlers.add(new ResponseBodyEmitterReturnValueHandler(this.getMessageConverters(), this.reactiveAdapterRegistry, this.taskExecutor, this.contentNegotiationManager));
            handlers.add(new StreamingResponseBodyReturnValueHandler());
            handlers.add(new HttpEntityMethodProcessor(this.getMessageConverters(), this.contentNegotiationManager, this.requestResponseBodyAdvice));
            handlers.add(new HttpHeadersReturnValueHandler());
            handlers.add(new CallableMethodReturnValueHandler());
            handlers.add(new DeferredResultMethodReturnValueHandler());
            handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));
            handlers.add(new ModelAttributeMethodProcessor(false));
            handlers.add(new RequestResponseBodyMethodProcessor(this.getMessageConverters(), this.contentNegotiationManager, this.requestResponseBodyAdvice));
            handlers.add(new ViewNameMethodReturnValueHandler());
            handlers.add(new MapMethodProcessor());
    if (this.getCustomReturnValueHandlers() != null) { handlers.addAll(this.getCustomReturnValueHandlers()); } if (!CollectionUtils.isEmpty(this.getModelAndViewResolvers())) { handlers.add(new ModelAndViewResolverMethodReturnValueHandler(this.getModelAndViewResolvers())); } else { handlers.add(new ModelAttributeMethodProcessor(true)); } return handlers; }

    总结

    1.通过请求适配对应的Handle

    2.通过Handle再适配对应的处理器,因为Handle会有多种形式存在,比如我们常用的就是存储了处理类 和处理方法 对应的处理器可以通过反射执行

    3.RequestMappingHandlerAdapter通过实现spring  InitializingBean来实现初始化入参绑定器   返回值绑定器   ControllerAdvice 的初始化 供后续使用

  • 相关阅读:
    1+X云计算(中级) 单节点部署应用商城系统(gpmall)
    1+X云计算 应用商城系统(gpmall)-遇到的问题以及解决办法
    1+X云计算平台运维与开发(中级)eNSP A~E卷 试题+答案
    vi&vim 基本使用方法
    yum针对软件包操作的常用命令
    本地yum源配置
    SpringCloud微服务初体验
    SpringBoot自定义注解拦截器,实现登录token验证
    MySQL建立SSL连接问题,设置useSSL=false显式禁用SSL,或者设置useSSL=true
    TPL事务
  • 原文地址:https://www.cnblogs.com/LQBlog/p/12220790.html
Copyright © 2020-2023  润新知