Spring MVC之RequestMappingHandlerAdapter初始化
2018-03-30 16:55
911 查看
RequestMappingHandlerAdapter基于注解的处理器适配器,目的是用来执行handler,同时返回modelAndView给前端控制器,这块个人感觉是spring mvc的核心了,所以我会详细一些记录。
本篇文章先记录他初始化都做了什么。
先上类图:
通过类图可以看到,实现了InitializingBean接口,所以入口的方法就是 afterPropertiesSet();
下面来看代码:
public void afterPropertiesSet() { List handlers; if (this.argumentResolvers == null) { //加载默认的参数解析器 handlers = this.getDefaultArgumentResolvers(); this.argumentResolvers = (new HandlerMethodArgumentResolverComposite()).addResolvers(handlers); } if (this.initBinderArgumentResolvers == null) { //加载@initBinder注解的解析器 handlers = this.getDefaultInitBinderArgumentResolvers(); this.initBinderArgumentResolvers = (new HandlerMethodArgumentResolverComposite()).addResolvers(handlers); } if (this.returnValueHandlers == null) { //加载默认返回值的解析器 handlers = this.getDefaultReturnValueHandlers(); this.returnValueHandlers = (new HandlerMethodReturnValueHandlerComposite()).addHandlers(handlers); } this.initControllerAdviceCache(); //缓存 类有@ControllerAdvice 且@ModelAttribute 和 @InitBinder的注解的方法 }
注意:这些解析器实际上都是一个*****Composite结尾的包装类,实际上就是责任链模式的管理类,提供查找具体的解析器和执行方法,这块内容就不多描述了.
就拿参数解析器为例:
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)); //没有注解的pojo对象参数 使用它解析的//@ResponseBody注解用的,实际上输入和输出都有他,他实现了俩接口
resolvers.add(new RequestResponseBodyMethodProcessor(this.getMessageConverters())); resolvers.add(new RequestPartMethodArgumentResolver(this.getMessageConverters())); 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 ServletRequestMethodArgumentResolver()); resolvers.add(new ServletResponseMethodArgumentResolver()); resolvers.add(new HttpEntityMethodProcessor(this.getMessageConverters())); 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; }
下面来看initControllerAdviceCache()方法
private void initControllerAdviceCache() { if (this.getApplicationContext() != null) { if (this.logger.isDebugEnabled()) { this.logger.debug("Looking for controller advice: " + this.getApplicationContext()); } //获取所有有@ControllerAdvice的Bean List<ControllerAdviceBean> beans = ControllerAdviceBean.findAnnotatedBeans(this.getApplicationContext()); Collections.sort(beans, new OrderComparator()); Iterator i$ = beans.iterator(); while(i$.hasNext()) { ControllerAdviceBean bean = (ControllerAdviceBean)i$.next(); //遍历bean拿到@ModelAttribute的方法 Set<Method> attrMethods = HandlerMethodSelector.selectMethods(bean.getBeanType(), MODEL_ATTRIBUTE_METHODS); if (!attrMethods.isEmpty()) { this.modelAttributeAdviceCache.put(bean, attrMethods); //缓存起来 this.logger.info("Detected @ModelAttribute methods in " + bean); } //拿到有@InitBinder的方法 Set<Method> binderMethods = HandlerMethodSelector.selectMethods(bean.getBeanType(), INIT_BINDER_METHODS); if (!binderMethods.isEmpty()) { this.initBinderAdviceCache.put(bean, binderMethods); //缓存起来 this.logger.info("Detected @InitBinder methods in " + bean); } } } }
到此为止,初始化完成
相关文章推荐
- Spring MVC之适配器的获取及执行(RequestMappingHandlerAdapter)
- Spring MVC 配置RequestMappingHandlerAdapter
- Spring MVC的handlermapping之RequestMappingHandlerMapping初始化
- mvc:annotation-driven 元素,HttpMessageConverter,RequestMappingHandlerAdapter
- SpringMVC之分析RequestMappingHandlerAdapter(二)
- 【Spring MVC】HandlerAdapter初始化详解(超详细过程源码分析)
- SpringMVC源码解读 - HandlerMapping - RequestMappingHandlerMapping初始化
- SpringMVC之分析RequestMappingHandlerAdapter(一)
- spring mvc 关键接口 HandlerMapping HandlerAdapter
- Spring MVC的handlermapping之SimpleUrlHandlerMapping初始化
- springMVC源码分析--RequestMappingHandlerAdapter(五)
- RequestMappingHandlerAdapter配置
- springMVC源码分析--RequestMappingHandlerAdapter(五)
- springMVC源码分析--RequestMappingHandlerAdapter(五)
- spring RequestMappingHandlerAdapter解析参数绑定到pojo过程
- 利用RequestMappingHandlerMapping提取Spring MVC @RequestMapping
- SpringMVC源码解读 - HandlerMapping - RequestMappingHandlerMapping初始化
- RequestMappingHandlerAdapter引起@Valid失效
- Spring MVC的handlermapping之请求分发如何找到正确的Handler(RequestMappingHandlerMapping)
- Spring MVC中用SimpleUrlHandlerMapping实现单纯的页面跳转