【有书共读】《Spring源码深度解读》第11章MVC
Springmvc分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让他们更容易进行定制。默认的处理程序是非常简单的Controller接口,只有一个方法ModelAndView handleRequest(request, response),spring提供了一个控制器层次结构,可以派生子类,如果应用程序需要处理用户输入表单,那么可以继承AbstractFormController。如果需要把多页输入处理到一个表单,那么可以继承AbstractWizardFormController。
Springmvc解决的问题:(1)将web页面的请求传递给服务器
(2) 根据不同的请求处理不同的逻辑单元
(3) 返回处理结果数据并跳转至响应的页面
11.1springmvc快速体验(本模块就是举例子,在这里只介绍知识点)
(一)配置web.xml
springmvc的实现原理是通过Servlet拦截所有的url来达到控制的目的web.xml是必须的。
之所以是必须的,最关键的地方有两个。
(1)contextConfigLocation:spring的核心就是配置文件,这个参数让web与spring的配置文件结合的一个关键配置。
(2)DispatcherServlet:包含了SpringMvc的请求逻辑,Spring使用此类拦截wen请求并进行相应的逻辑处理。
(二)创建applicationContext.xml
(三)创建model
(四)创建controller
(五)创建Servlet配置文件spring-servlet.xml
因为SpringMVC是基于Servlet的实现,所以在web启动的时候,服务器会首先尝试加载对应与Servlet的配置文件,为了让项目更加模块化,通常我们将web部分的配置都存放于此配置文件中。
11.2ContextLoaderListen(web.xml文件中的配置)
ContextLoaderListener的作用就是启动web容器时,自动装配applicationContext的配置信息。因为它实现了ServlerContextListener这个接口,在web.xml配置这个***,启动容器时,就会默认执行它实现的方法,使用ServletContextListen接口.
(一)ServletContextListener的使用
在启动ServletContextListener实现类的时候会调用contextInitialized方法
(二)Spring中的ContextLoaderListener
ContextLoaderListener的实现方式和servletContextListener差不多。servletContext启动之后会调用servletContextListener的contextInitialized方法->initWebApplicationContext方法。在这两个方法中,我们得出了初始化的大致步骤
(1)WebApplicationContext的存在性验证。配置文件中只允许声明一次Servlet Context Listener,多次声明会扰乱spring的执行逻辑。在spring中如果创建WebApplicationContext实例会记录在ServletContext中
(2)创建WebApplicationContext实例。如果通过了验证,则Spring的WebApplicationContext实例的工作委托给了createWebApplicationContext函数。
综合以上代码分析,在初始化过程中,程序首先读取ContextLoader类的同目录下的属性文件ContextLoader.properties,并根据其中的配置提取要实现WebApplicationContext接口的实现类,并根据这个实现类通过反射的方式进行实例的创建。
(3)将实例记录在servletContext中
(4)映射当前的类加载器与创建的实例到全局变量currentContextPerThread。
11.3DispatcherServlet
在spring中,contextLoaderListener只是辅助功能,用于创建WebApplicationContext类型实例,真正的逻辑实现是在DispatcherServlet中进行的,SispatcherServlet是实现Servlet接口的实现类。
Servlet是一个java编写的程序,此程序是基于http协议的,在服务器端运行,是按照servlet规范编写的java类。主要是处理客户端的请求并将其结果发送到客户端。Servlet的生命周期是由servlet的容器控制的,分为三个阶段:初始化、运行和销毁。
(一)建立servlet
Init方法保证在servlet加载的时候做一些逻辑***作
(二)DispatcherServlet的初始化
DispatcherServlet的初始化过程主要是通过将当前的servlet类型转换为BeanWrapper类型实例,以便使用Spring中提供的注入功能进行对属性的注入。
属性注入的步骤:(1)封装及验证初始化参数
(2)将当前servlet实例转换为BeanWrapper实例
(3)注册相对于Resource的属性编辑器
(4)属性注入
(5)servletBean的初始化
(三)webApplication的初始化
InitWebApplicationContext函数的主要作用就是创建或刷新WebApplication实例并对servlet功能锁使用的变量初始化。本函数的初始化包含一下积分部分:
(1)寻找或创建对应的WebApplication实例
A. 通过构造函数的注入进行初始化
B. 通过contextAttribute进行初始化
C. 重新创建WebApplication实例
(2)configureAndRefreshWebApplicationContext
对已经创建的webapplication实例进行配置及刷新
(3)刷新
onFresh是FrameworkServlet类中提供的模板方法,在其子类DispatcherServlet中进行了重写,主要用于刷新在web功能视线中所必须使用的全局变量。
(5)初始化HandlerAdapters
(6)初始化HandlerExceptionResolvers
(7)初始化RequestToViewNameTranslator
(8)初始化ViewResolver
11.4DispatcherServlet的处理逻辑
根据之前的示例,在httpServlet类中分别提供了相应的服务方法,分别是doDelete(),doGet(),doOptions(),doPost,doPut(),doTrace(),它会根据不同的形式将程序引导至对应的函数进行处理。这几个函数中最常用的是doGet(),doPost(),在这两个方法中,都调用了precessRequest(request, response)方法,此方法中调用了doService()方法。