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     }

到此为止,初始化完成


原文地址:https://www.cnblogs.com/haoerlv/p/8677256.html