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 的初始化 供后续使用

posted @ 2020-01-21 10:14  意犹未尽  阅读(341)  评论(0编辑  收藏  举报