zoukankan      html  css  js  c++  java
  • Spring MVC之RequestMappingHandlerAdapter初始化

    RequestMappingHandlerAdapter基于注解的处理器适配器,目的是用来执行handler,同时返回modelAndView给前端控制器,这块个人感觉是spring mvc的核心了,所以我会详细一些记录。
    本篇文章先记录他初始化都做了什么。
    先上类图:

    通过类图可以看到,实现了InitializingBean接口,所以入口的方法就是 afterPropertiesSet();

    下面来看代码:

     1     public void afterPropertiesSet() {
     2         List handlers;
     3         if (this.argumentResolvers == null) { //加载默认的参数解析器  
     4             handlers = this.getDefaultArgumentResolvers();
     5             this.argumentResolvers = (new HandlerMethodArgumentResolverComposite()).addResolvers(handlers);
     6         }
     7 
     8         if (this.initBinderArgumentResolvers == null) { //加载@initBinder注解的解析器
     9             handlers = this.getDefaultInitBinderArgumentResolvers();
    10             this.initBinderArgumentResolvers = (new HandlerMethodArgumentResolverComposite()).addResolvers(handlers);
    11         }
    12 
    13         if (this.returnValueHandlers == null) { //加载默认返回值的解析器
    14             handlers = this.getDefaultReturnValueHandlers();
    15             this.returnValueHandlers = (new HandlerMethodReturnValueHandlerComposite()).addHandlers(handlers);
    16         }
    17 
    18         this.initControllerAdviceCache(); //缓存 类有@ControllerAdvice 且@ModelAttribute 和 @InitBinder的注解的方法
    19     }

    注意:这些解析器实际上都是一个*****Composite结尾的包装类,实际上就是责任链模式的管理类,提供查找具体的解析器和执行方法,这块内容就不多描述了.

    就拿参数解析器为例:

     1     private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
     2         List<HandlerMethodArgumentResolver> resolvers = new ArrayList();
     3         resolvers.add(new RequestParamMethodArgumentResolver(this.getBeanFactory(), false));
     4         resolvers.add(new RequestParamMapMethodArgumentResolver());
     5         resolvers.add(new PathVariableMethodArgumentResolver());
     6         resolvers.add(new PathVariableMapMethodArgumentResolver());
     7         resolvers.add(new MatrixVariableMethodArgumentResolver());
     8         resolvers.add(new MatrixVariableMapMethodArgumentResolver());
     9         resolvers.add(new ServletModelAttributeMethodProcessor(false)); //没有注解的pojo对象参数 使用它解析的
                 //@ResponseBody注解用的,实际上输入和输出都有他,他实现了俩接口 
    10         resolvers.add(new RequestResponseBodyMethodProcessor(this.getMessageConverters())); 
    11         resolvers.add(new RequestPartMethodArgumentResolver(this.getMessageConverters()));
    12         resolvers.add(new RequestHeaderMethodArgumentResolver(this.getBeanFactory()));
    13         resolvers.add(new RequestHeaderMapMethodArgumentResolver());
    14         resolvers.add(new ServletCookieValueMethodArgumentResolver(this.getBeanFactory()));
    15         resolvers.add(new ExpressionValueMethodArgumentResolver(this.getBeanFactory()));
    16         resolvers.add(new ServletRequestMethodArgumentResolver());
    17         resolvers.add(new ServletResponseMethodArgumentResolver());
    18         resolvers.add(new HttpEntityMethodProcessor(this.getMessageConverters()));
    19         resolvers.add(new RedirectAttributesMethodArgumentResolver());
    20         resolvers.add(new ModelMethodProcessor());
    21         resolvers.add(new MapMethodProcessor());
    22         resolvers.add(new ErrorsMethodArgumentResolver());
    23         resolvers.add(new SessionStatusMethodArgumentResolver());
    24         resolvers.add(new UriComponentsBuilderMethodArgumentResolver());
    25         if (this.getCustomArgumentResolvers() != null) { //自定义的参数解析器
    26             resolvers.addAll(this.getCustomArgumentResolvers());
    27         }
    28 
    29         resolvers.add(new RequestParamMethodArgumentResolver(this.getBeanFactory(), true)); //据说全能的,有时间看下代码
    30         resolvers.add(new ServletModelAttributeMethodProcessor(true));
    31         return resolvers;
    32     }

    下面来看initControllerAdviceCache()方法

     1     private void initControllerAdviceCache() {
     2         if (this.getApplicationContext() != null) {
     3             if (this.logger.isDebugEnabled()) {
     4                 this.logger.debug("Looking for controller advice: " + this.getApplicationContext());
     5             }
     6        //获取所有有@ControllerAdvice的Bean
     7             List<ControllerAdviceBean> beans = ControllerAdviceBean.findAnnotatedBeans(this.getApplicationContext());
     8             Collections.sort(beans, new OrderComparator());
     9             Iterator i$ = beans.iterator();
    10 
    11             while(i$.hasNext()) {
    12                 ControllerAdviceBean bean = (ControllerAdviceBean)i$.next(); //遍历bean拿到@ModelAttribute的方法
    13                 Set<Method> attrMethods = HandlerMethodSelector.selectMethods(bean.getBeanType(), MODEL_ATTRIBUTE_METHODS);
    14                 if (!attrMethods.isEmpty()) {
    15                     this.modelAttributeAdviceCache.put(bean, attrMethods); //缓存起来
    16                     this.logger.info("Detected @ModelAttribute methods in " + bean);
    17                 }
    18           //拿到有@InitBinder的方法
    19                 Set<Method> binderMethods = HandlerMethodSelector.selectMethods(bean.getBeanType(), INIT_BINDER_METHODS);
    20                 if (!binderMethods.isEmpty()) {
    21                     this.initBinderAdviceCache.put(bean, binderMethods); //缓存起来
    22                     this.logger.info("Detected @InitBinder methods in " + bean);
    23                 }
    24             }
    25 
    26         }
    27     }

    到此为止,初始化完成

    
    
  • 相关阅读:
    Poj-1088-滑雪
    Poj-2250-Compromise
    CF
    KMP算法
    01背包
    NY 269 VF
    PHP--1+2+3……100=?
    PHP企业发放的奖金--if...elseif...
    2019年中级考试题(附答案)
    PHP的IF条件语句-- 输入一个数字进行判断等级
  • 原文地址:https://www.cnblogs.com/haoerlv/p/8677256.html
Copyright © 2011-2022 走看看