昨天重新看了一遍Spring的源码,着重看了一下Spring MVC对请求参数的解析部分,但是发现如果要对这块有更好的理解首先要先明白SpringMVC所特有的一些类(比如)是怎么初始化的

这里我只是说一下初始化流程,具体的代码就不说了(太详细可能我也说不出来

),只是做个备注:

因为我们一般在web.xml中配置DispatcherServlet的时候load-on-startup设置为立即执行,那么在容器启动后(即Spring初始化完成后),那么执行servlet的init方法进入SpringMVC初始化入口:

spring 如何启动时最后加载某个类 springmvc启动时加载类_MVC

这里的this直接指向HttpSerletBean.init方法

spring 如何启动时最后加载某个类 springmvc启动时加载类_spring 如何启动时最后加载某个类_02

接着,调用子类FrameworkServlet的initServletBean()方法:

spring 如何启动时最后加载某个类 springmvc启动时加载类_初始化_03

可以看到这里初始化了WebApplicationContext亦即SpringMVC的容器,我们看一下在容器初始化的时候做了哪些工作(FrameworkServlet.initWebApplicationContext());

spring 如何启动时最后加载某个类 springmvc启动时加载类_监听器_04

接着进入createWebApplicationContext(rootContext);

spring 如何启动时最后加载某个类 springmvc启动时加载类_初始化_05

可以看到这里初始化了一个XmlWebApplicationContext的实例,并通过configureAndRefreshWebApplicationContext(wac)方式对该实例进行一些设置:

spring 如何启动时最后加载某个类 springmvc启动时加载类_MVC_06

注意标黄的那个Listener,后面再refresh的执行过程中会调用该listener的onApplicationEvent方法,接下来执行wac.refresh()方法:

spring 如何启动时最后加载某个类 springmvc启动时加载类_spring 如何启动时最后加载某个类_07

可以看到这里做了一些列的操作,包括事件广播初始化、注册事件以及最后的发布事件

spring 如何启动时最后加载某个类 springmvc启动时加载类_初始化_08

AbstractApplicationContext.publicEvent:

spring 如何启动时最后加载某个类 springmvc启动时加载类_spring 如何启动时最后加载某个类_09

通过SimpleApplicationEventMulticaster发布事件

spring 如何启动时最后加载某个类 springmvc启动时加载类_MVC_10

执行监听器:

spring 如何启动时最后加载某个类 springmvc启动时加载类_MVC_11

这里执行的监听器包括所以在spring中声明的ApplicationListener实例(猜测),当然也包括刚才的那个SourceFilteringListener监听器:

spring 如何启动时最后加载某个类 springmvc启动时加载类_监听器_12

在执行监听器SourceFilteringListener的过程中,该类通过一系列的delege模式最终执行到FrameworkServlet的内部类ContextRefreshListener的onApplicationEvent方法:

spring 如何启动时最后加载某个类 springmvc启动时加载类_spring 如何启动时最后加载某个类_13

spring 如何启动时最后加载某个类 springmvc启动时加载类_MVC_14

spring 如何启动时最后加载某个类 springmvc启动时加载类_MVC_14

spring 如何启动时最后加载某个类 springmvc启动时加载类_初始化_16

spring 如何启动时最后加载某个类 springmvc启动时加载类_MVC_17


可以看到,在initStrategies方法中就出现了初始化HandlerAdapter和HandlerMapping的方法,而我们常用的RequestMappingHandlerAdapter和RequestMappingHandlerMapping都直接或者间接的实现了InitializingBean接口,而这个接口唯一的实现方法afterPropertiesSet是在所有bean初始化后执行,那么我们看一下这两个类中的afterPropertiesSet中各自实现了什么:

RequestMappingHandlerAdapter:

spring 如何启动时最后加载某个类 springmvc启动时加载类_MVC_18

可以看到,HandlerAdapter的afterPropertiesSet初始化了参数及返回值的解析类

HanlderMapping

spring 如何启动时最后加载某个类 springmvc启动时加载类_初始化_19

而HandlerMapping则是注册所有的HandlerMethod。

看了一遍代码才知道,原来Spring在初始化的时候做了这么多时期,也知道了原来参数解析器和返回值解析器实在监听器执行的过程中通过HandlerAdapter的afterPropertiesSet方法实现的。通过这么一次代码的阅读加深了我对springmvc的理解,以后还是要抽时间多看一下源码的。