Spring MVC之RequestMappingHandlerAdapter初始化
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对象参数 使用它解析的
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之DispatcherServlet初始化详解
Spring作为一个优秀的web框架,其运行是基于Tomcat的.在我们前面的讲解中,Spring的驱动都是使用的ClassPathXmlApplicationContext,并且都是直接在main方 ...
- Spring MVC启动时初始化的几个常用方法
Spring-MVC的应用中,要实现类似的功能,主要是通过实现下面这些接口(任选一,至少一个即可) 一.ApplicationContextAware接口 +? 1 2 3 4 5 6 7 8 9 p ...
- Spring MVC(一)--SpringMVC的初始化和流程
SpringMVC是Spring提供给WEB应用的MVC框架,MVC框架一般来说由三部分组成: Model:模型层,一般由java bean完成,主要是进行数据库操作: View:视图层,用于前端展示 ...
- spring mvc之请求过程源码分析
简介 上一篇,我们分析了spring mvc启动过程的源码,这一节,来一起分析下在用户请求controller的过程中,spring mvc做了什么事? 一.准备 我写这么一个controller p ...
- Spring MVC组件之HandlerAdapter
Spring MVC组件之HandlerAdapter HandlerAdapter概述 HandlerAdapter组件是一个处理器Handler的适配器.HandlerAdapter组件的主要作用 ...
- 【WEB】初探Spring MVC框架
Spring MVC框架算是当下比较流行的Java开源框架.但实话实说,做了几年WEB项目,完全没有SpringMVC实战经验,乃至在某些交流场合下被同行严重鄙视“奥特曼”了.“心塞”的同时,只好默默 ...
- Spring MVC源码分析(续)——请求处理
转自:http://blog.csdn.net/shi1122/article/details/8041017 (转移位置了,时光隧道:http://www.jmatrix.org/spring/50 ...
- Spring MVC 实践 - Base
Spring MVC 实践 标签 : Java与Web Spring Web MVC Spring-Web-MVC是一种基于请求驱动的轻量级Web-MVC设计模式框架, Spring MVC使用MVC ...
- 《Spring技术内幕》笔记-第四章 Spring MVC与web环境
上下文在web容器中的启动 1,IoC容器的启动过程 IoC的启动过程就是建立上下文的过程.该上下文是与ServletContext相伴.在Spring中存在一个核心控制分发器,Dispatcher ...
随机推荐
- nginx 配置实现逻辑预算
nginx 的配置 不支持逻辑与和逻辑非运算,也不支持if 嵌套,只能用其他方式实现 set $flag 0; if ($host != name) { set $flag "${flag} ...
- Reusing & Composing GraphQL APIs with GraphQL Bindings
With GraphQL bindings you can embed existing GraphQL APIs into your GraphQL server. In previous blog ...
- Maven管理SSM框架的pom.xml文件配置(自己主动下载所依赖的jar包)
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/UP19910522/article/details/25403855 <project xml ...
- Hive之 数据存储
首先,Hive 没有专门的数据存储格式,也没有为数据建立索引,用户可以非常自由的组织 Hive 中的表,只需要在创建表的时候告诉 Hive 数据中的列分隔符和行分隔符,Hive 就可以解析数据. 其次 ...
- 显示Deprecated: Assigning the return value of new by reference is deprecated in解决办法
很多朋友的php程序当php的版本升级到5.3以后,会出现”Deprecated: Assigning the return value of new by reference is deprecat ...
- vim配置之安装脚本
vimConfig/install/install.sh git clone https://github.com/gmarik/vundle.git ~/.vim/bundle/vundle cp ...
- Bootstrap-Other:UI 编辑器
ylbtech-Bootstrap-Other:UI 编辑器 1.返回顶部 1. Bootstrap UI 编辑器 以下是 15 款最好的 Bootstrap 编辑器或者是在线编辑工具. 1. Boo ...
- 管理Linux服务器的用户和组(续篇)
用户切换 新建用户 useradd命令的选项 设置用户口令 passwd命令的选项 chage命令 修改用户帐户 禁用和恢复用户帐户 禁用和恢复用户帐户- Passwd命令 禁用和恢复用户帐户-直接修 ...
- 【转载】Python ConfigParser的使用
1.基本的读取配置文件-read(filename) 直接读取ini文件内容-sections() 得到所有的section,并以列表的形式返回-options(section) 得到该section ...
- tensorflow-windows下安装,python3.6
安装: pip install tensorflow ps:我第一次安装了,但是导入却失败了. 进入\python3\Lib\site-packages\删除了tensorflow,再次pip ins ...