Spring技术内幕——Spring MVC
- model:
封装应用数据状态(参数解析器),响应数据状态查询(数据库),提供应用功能接口(模型本该做的事),数据状态变化通知视图(返回值处理器) - view:
通过视图展现应用数据,向应用数据提供更新请求,向控制器提交用户动作,运行控制器选择不同的视图 - control:
dispatcherservlet:定义应用的功能,映射用户动作到数据更新,选择对应的视图,一个控制器对应一组功能
Web容器ServletContext
web.xml配置文件:首先定义一个dispatcherservlet,相应的url映射;指定Spring IoC容器读取Bean定义的xml的文件的路径;最后作为Spring MVC的启动类,ContextLoaderListener被定义为一个监听器,与web服务器的生命周期相关联,负责监听Web容器的事件并完成IoC容器和WebMVC相关上下文的创建。
对于一个web应用,其部署在web容器中,web容器提供一个全局的上下文环境,就是ServletContext,ServletContext为Spring的IoC容器提供了一个宿主环境。
IoC容器的启动过程WebApplicationContext
作为根上下文(在向IoC容器getBean的时候,IoC容器会首先向其双亲上下文getBean,因此根上下文定义的Bean可以被各个Servlet持有的上下文得到和共享),WebApplicationContext,在服务器启动,ServletContext创建时,触发容器初始化事件,由ContextLoaderListener启动,由contextInitialized()实现,WebApplicationContext是一个接口类,默认的实现类是XmlWebApplicationContext。这个IoC初始化完毕后以常量键存放在ServletContext中,以便后续通过索引取得根上下文。
WebApplicationContext接口类中定义了一个getServletContext方法,通过这个方法可以获得Web容器级别的全局环境。
ContextLoaderListener通过使用ContextLoader来完成webapplicationcontext容器的初始化工作。
contextLoader.initWebApplicationContext:creatWebApplicationContext:wac.setParent(parent);wac.refresh()
Spring MVC(DispatcherServlet)
在ContextLoaderListener完成初始化根上下文的工作后,Web容器开始初始化DispatcherServlet,初始化的启动与web.xml载入次序有关。DispatcherServlet会建立自己的上下文来持有SpringMVC的Bean对象,在建立这个自己持有的IoC容器时,会从ServletContext中得到根上下文wac作为自己的双亲上下文。有了根上下文后,对自己持有的上下文初始化,最后将自己持有的上下文保存到ServletContext中,以便检索使用。
DispatcherServlet
-
初始化部分:由initServletBean()启动,通过initWebApplicationContext()方法调用DispatcherServlet的initStrategies方法,在这个方法里对MVC模块的其他部分进行了初始化,比如handlerMapping、ViewResolver、adapters等;
DispatcherServlet持有的上下文是和Servlet对应的一个上下文。
以handlerMappings为例,会先从其他容器中试图取得,未果后通过读取配置文件或者注解自己创建,在容器初始化的过程中确立了其BeanDefinition,读取其中的映射关系并完成初始化。 -
对Http请求响应,作为一个servlet,Web容器会调用Servlet的doGet()、doPost(),后续调用processRequest(),调用DispatcherServlet的doService(),封装了doDispatch(),这个方法是核心。
handlerMapping持有一系列从URL请求到Controller的映射,使SpringMVC应用可以根据HTTP请求确定一个对应的Controller。在HandlerMapping接口定义了getHandler方法,通过这个方法获得与HTTP请求相对应的HandlerExecutionChain,在这个执行链中封装了具体的Controller对象。
HandlerExecutionChain持有一个Interceptor链(为handler对象功能的增强)和一个handler对象(HTTP请求对应的Controller)。
doDispatch(request,response):
getHandler()(先从缓存中找,没找到再去DispatcherServlet持有的HandlerMapping中生成一个,得到HandlerExecutionChain),拦截器preHandler,handler,postHandler
在modelandview中寻找视图对象的逻辑名,并对其进行解析,得到需要的视图对象,调用render方法