Spring Mvc结构解析

上图是Dispatcher Servlet的结构图,从图中可以清楚的看到Dispatcher Servlet的继承链,下面我们将基于Spring4.1.6揭开Spring MVC的神秘面纱。

初始化过程

我们都知道,Java中初始化顺序是:

  1. 初始化父类静态变量(静态代码块,静态变量,静态方法,需要注意的是main方法也是静态的)
  2. 初始化子类静态变量(范围同父类)
  3. 初始化父类普通成员变量及方法
  4. 调用父类构造方法
  5. 初始化子类普通成员变量及方法
  6. 调用子类构造方法

那么,在Dispatcher Servlet初始化的时候也是严格按照这个顺序来执行的。我们分别来看看在不同阶段都做了些什么。

HttpServletBean初始化过程关键代码

   @Overridepublic final void init() throws ServletException {//  从spring的配置文件中读取servlet的Init-Param。即spring配置文件路径等关键配置try {PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));initBeanWrapper(bw);bw.setPropertyValues(pvs, true);}catch (BeansException ex) {logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);throw ex;}// 调用frameworkServlet的方法初始化initServletBean();}

FrameworkServlet初始化过程关键代码

    @Overrideprotected final void initServletBean() throws ServletException { this.webApplicationContext = initWebApplicationContext(); }protected WebApplicationContext initWebApplicationContext() {WebApplicationContext rootContext =WebApplicationContextUtils.getWebApplicationContext(getServletContext());WebApplicationContext wac = null;if (wac == null) {// 在这里初始化Spring MVC的context,并将Spring MVC的context和Servlet Context绑定wac = createWebApplicationContext(rootContext);}return wac;}protected WebApplicationContext createWebApplicationContext(ApplicationContext parent) {Class<?> contextClass = getContextClass();// 通过反射new一个空的context对象返回ConfigurableWebApplicationContext wac =(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);wac.setEnvironment(getEnvironment());wac.setParent(parent);wac.setConfigLocation(getContextConfigLocation());//  在这里会调用onRefreah方法,初始化Dispatcher Servlet的9大策略configureAndRefreshWebApplicationContext(wac);return wac;}protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {if (ObjectUtils.identityToString(wac).equals(wac.getId())) {// The application context id is still set to its original default value// -> assign a more useful id based on available informationif (this.contextId != null) {wac.setId(this.contextId);}else {wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +ObjectUtils.getDisplayString(getServletContext().getContextPath()) + "/" + getServletName());}}// 为web application context设置基本属性wac.setServletContext(getServletContext());wac.setServletConfig(getServletConfig());wac.setNamespace(getNamespace());wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));ConfigurableEnvironment env = wac.getEnvironment();if (env instanceof ConfigurableWebEnvironment) {((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());}postProcessWebApplicationContext(wac);applyInitializers(wac);// 关键,这里会刷新整个context,调用Dispatcher Servlet的onRefreah方法。初始化一系列Resolverswac.refresh();}

DispatcherServlet初始化过程关键代码

    /*** This implementation calls {@link #initStrategies}.*/@Overrideprotected void onRefresh(ApplicationContext context) {initStrategies(context);}/*** Initialize the strategy objects that this servlet uses.* <p>May be overridden in subclasses in order to initialize further strategy objects.*/protected void initStrategies(ApplicationContext context) {initMultipartResolver(context);initLocaleResolver(context);initThemeResolver(context);// 寻找配置的HandlerMapping,下篇文章我们会继续分析这里的详细过程。是url映射controller的关键,默认是RequestMappgingHandlerMapping和BeanNameUrlHandlerMapping,这些HandlerMapping会在spring context初始化的时候初始化。initHandlerMappings(context);// 寻找配置的适配器,默认是RequestMappingHandlerAdapter,HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter这三种initHandlerAdapters(context);initHandlerExceptionResolvers(context);initRequestToViewNameTranslator(context);initViewResolvers(context);initFlashMapManager(context);}

从上面的关键部分代码可以看出Spring MVC在启动时的的大概流程,大致了解Spring MVC都做了什么。后续会继续分析请求到达Dispatcher Servlet后是如何找到对应的controller以及参数封装,最后再到数据返回等流程的详细过程。

Spring MVC源码解析相关推荐

  1. Spring MVC源码解析——HandlerMapping(处理器映射器)

    Sping MVC 源码解析--HandlerMapping处理器映射器 1. 什么是HandlerMapping 2. HandlerMapping 2.1 HandlerMapping初始化 2. ...

  2. Spring MVC源码——Servlet WebApplicationContext

    上一篇笔记(Spring MVC源码--Root WebApplicationContext)中记录了下 Root WebApplicationContext 的初始化代码.这一篇来看 Servlet ...

  3. spring boot 源码解析23-actuate使用及EndPoint解析

    前言 spring boot 中有个很诱人的组件–actuator,可以对spring boot应用做监控,只需在pom文件中加入如下配置即可: <dependency><group ...

  4. Spring MVC源码——Root WebApplicationContext

    Spring MVC源码--Root WebApplicationContext 打算开始读一些框架的源码,先拿 Spring MVC 练练手,欢迎点击这里访问我的源码注释, SpringMVC官方文 ...

  5. spring事务源码解析

    前言 在spring jdbcTemplate 事务,各种诡异,包你醍醐灌顶!最后遗留了一个问题:spring是怎么样保证事务一致性的? 当然,spring事务内容挺多的,如果都要讲的话要花很长时间, ...

  6. Spring AOP源码解析-拦截器链的执行过程

    一.简介 在前面的两篇文章中,分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在得到了 bean 的代理对象,且通知也以合适的方式插在了目标方 ...

  7. Spring Session源码解析

    AbstractHttpSessionApplicationInitializer,很明显它是一个初始化的类,它是一个抽象类,可以理解为一个公用的基类,然后看一下onStartup这个方法,最主要的方 ...

  8. Spring AOP源码解析(一)——核心概念

    目录 Pointcut ClassFilter MethodMatcher Advisor IntroductionAdvisor PointcutAdvisor AbstractPointcutAd ...

  9. Spring @Import源码解析

    在Spring boot中常用到@Import,允许通过它引入 @Configuration 注解的类 (java config), 引入ImportSelector接口(这个比较重要, 因为要通过它 ...

最新文章

  1. 大学计算机html,编程基础(C+VB+HTML)(辅)19级计算机
  2. GraphQL 学习
  3. 三刷进博 | 跨界直播,组团参展,施耐德电气有备而来!
  4. Windows驱动开发学习笔记(二)—— 驱动调试内核编程基础
  5. redis 正则匹配value_Redis 获取匹配所有的key
  6. 写出TREE-MINIMUM 和TREE-MAXIMUM的递归版本(算法导论第三版12.2-2)
  7. Impress.js上手 - 抛开PPT、制作Web 3D幻灯片放映
  8. linux多cpu运行python脚本,linux系统使用python获取cpu信息脚本分享
  9. 读书笔记《React:引领未来的用户界面开发框架》
  10. Unity3D调用android方法(非插件方式)
  11. make though multi core
  12. linux设置进程不忽略信号,Linux下后台进程编写中屏蔽信号
  13. Sublime 高亮汇编asm文件
  14. Django下进行urlencode编码,可以编码中文参数的代码
  15. HammerDB造数报错
  16. 如何解决浏览器音视频video/audio设置自动播放autoplay无效问题?
  17. 掌握NestJS - JavaScript Node.js 框架
  18. 华为发布新一代CloudLink视讯解决方案
  19. 刚刚!国产大数据基础软件第一股星环科技成功上市,开盘大涨超52%
  20. JAVA:(游戏:四子连)

热门文章

  1. Velocity语法大全
  2. 一次生产事故的优化经历
  3. C++操作SQLite数据库
  4. javaweb学习总结(三十一)——国际化(i18n)
  5. 【OpenCV3】双线性插值
  6. 第三日:继续恢复网站
  7. Golang基础之数组
  8. java 省市区数据data
  9. 个人申请并部署阿里云免费Symantec SSL过程浅谈
  10. 参加web前端学习前需要知道的注意事项