MVC(模型视图控制器):这是一种软件体系结构设计模式,分为三个部分:
它的主要目的是模块化代码以减少每一层之间的耦合,每个模块符合单个责任的原理。
Web框架的许多应用程序都是基于MVC模式设计的。春天也不例外。它还提供基于MVC的Web Framework Spring Web MVC,通常我们称为SpringMVC。
在实际开发中,我相信我们对SpringMVC的使用非常熟悉,因此在下一个源分析之前,我们将在SpringMVC中介绍一些基本知识。
支持的功能作为网络框架,SpringMVC还提供了许多丰富的功能:
dispatcherservlet,让我们首先看一下其类图,
它是前端控制器,SpringMVC的核心和Servlet的实现子类。它的主要功能是处理请求。执行请求映射,查看分析,异常处理和其他功能的功能;我们可以将其视为ITIT是SpringMVC中的真实服务器。
服务配置与IOC,AOO等相同,SpringMVC的Servlet配置也支持两种配置方法,即:::
关键的BeanSpringMVC定义了九种特殊豆类,以完成负责处理请求和不同策略的返回渲染。他们的分工显然不会互相干扰,即:
与以前春季的初始化过程(例如IOC和AOP)的复杂性相比,MVC更容易,并且可能是春季源分析中最简单的链接。让我们从它开始。
我刚刚在SpringMVC中介绍了9种特殊豆。我们可能知道它们各自的功能,并且SpringMVC的初始化过程实际上与它们一一相关。
从0到1,我们仍然需要找到初始化过程的入口。在上一个servlet配置中,已经引入了服务的初始化方法。XML的配置基于xmlwebapplicationContext容器。代码配置基于加载的AnnotionConfigwebapplicontext容器;在这里,我们主要分析基于代码的配置方法的初始分解过程。
写一个非常简单的测试演示:
通过想法配置tomcat容器,访问启动后,并成功查看页面上的显示。
接下来,我们开始逐步探索其初始化过程。
首先注册dispatcherservlet,我们需要创建一个IOC容器annotationConfigweBapplicationContext。它是上一次IOC解析中AntotionConfigapplicationContext的网络版本;然后,我们设置了IOC扫描路径,主要用于扫描我们编写的贡献者。
我们知道,调度员是Servlet的实施子类。在理解它之前,我们首先了解服务。
Servlet是Web服务器中运行的Java程序,其生命周期如下,
接下来,创建dispatcherServlet对象,注册IOC容器,然后将调度员注册到容器的servlet,然后设置两个属性:
可以发现这些方法称为servlet的原始API,而真实的处理代码由Web容器中的Servlet规范接口实现。我们最重要的是要注意实施Servlet Antibe API在SpringMVC中,即DispatcherServlet类,也是SpringMVC的核心。
初始化servlet,我们已经知道,在服务实例之后,我们将首先调用init()方法。但是,我们去检查dispatcherservlet源代码,找不到此方法。然后,该方法必须进行具体实现,让我们检查顶部级别父界接口服务的源代码:
Discovery Init()方法由子类GenericServlet实施。
这是一个自定义的init()方法,其特定实现实际上被委托给子类HttpservletBean以完成。
我们主要注意调用InitvletBean()方法来初始化服务,并且通过FrameworkServlet完成了特定方法实现。
通过源代码,我们看到主要是调用initwebapplicationContext()方法来初始化WebApplicationContext。我们知道,在注册dispatcherservlet之前已经创建了WebApplicationContext实例。
您可以在此处查看初始化WebApplicationContext的过程的过程逻辑,如下所示:
在此处实现该方法之后,它也是Servlet的初始化,即DispatcherServlet,这也意味着已启动Web容器。
初始化相关的组件,我们知道dispatcherservlet是SpringMVC的核心,它封装了MVC中的各种组件。然后,我们将研究如何完成上面的onrefresh()方法中MVC组件的初始化?
首先请注意,OnRefresh()方法是由FrameworkServlet委托Sub -Class DispatcherSert实施的。查看源代码。
此处的实现代码由每个组件的初始化方法封装,这是:
如果您单击以查看它们各自的初始化逻辑会发现它很简单。实际上,它已实例化为九个键豆。某些组件将使用默认配置在没有配置的情况下解决处理。它也已被引入,并且没有用于分析每个组件的初始化方法的源代码。
在上述初始化过程成功完成Web容器的开始之后,我们接下来考虑了服务器接收客户端的请求时,SpringMVC如何分析请求?
首先,返回Servlet的生命周期,我们知道该服务将始终存在于Web容器中,然后通过Service()方法处理客户端请求,然后我们将从此入口进行分析。
1.开始解析dispatcherservlet的类图,检查顶部级别界面界面服务接口的Service()方法,并找到编写的Quilt类Frameworklet。
当请求同时不为空时,它是补丁,将调用父httpservlet的服务()方法。
发现这实际上是不同请求方法的处理方法,并且实际上将处理方法(例如Doget(),dopost(),doput()实际上移交给了frameworkservlet来实现它,并将最终请求处理用于ProcessRequest()完成,
分析源代码知道,此处主要是在请求之前和之后准备和事件处理。为了确保请求之前和之后的原始属性,由社区派遣服务的doservice()方法和dispatchervlet完成了具体详细信息。
逻辑相对简单。主要角色是为请求的处理做准备。在MVC中相关组件的配置中,可以使用相关组件配置的MVC中的属性,以稍后进行分析,以稍后进行分析,
在准备层之后,最终显示了特定请求的分析处理逻辑,并且在此也反映了先前初始化的相关组件的作用。次要,源代码的特定处理逻辑将分别解析。
2.多部分请求转换将首先调用checkmultipart()方法,以检查是否需要将当前请求转换为包含文件上传的多部分部分。
如果以前没有多余的解析器,则将跳过此处的支票;否则,它将调用ismultipart()确定当前请求是否是请求的多个部分。MultiparthttpServletRequest,如果您查看其类图,您会发现它实际上是httpservletrequest的扩展名。Resolvemultipart()转换处理的源代码也很复杂,并且可以研究兴趣。
3.获取相应的处理程序检查请求,然后调用Gethandler()方法以使处理器与当前请求相对应,即与请求路径相对应的控制器。让我们看看如何找到它。
这里的handlermappings是列表集合。初始化时,将加载两个URL映射器:
在这里,我们仍然使用普通设置方法进行requestMappingHandLermapping来分析如何与控制器匹配URL。让我们看看gethandler()源代码,
将匹配的Interceptor HandlerInterceptor添加到执行链中;最终确定当前请求是否是交叉域请求,然后再次处理包装执行链操作链。
在这里,负责链的处理模式用于减少请求对象和处理器的耦合,这些链接可以轻松扩展和拦截请求分析。
让我们看一下子类AsptracthandLermetHodMapping中Gethandlerinal()的特定实现,
通过上述代码,您可以看到此处的URL匹配搜索将首先添加读取锁。我们知道读取锁已共享,并且写作锁定是完全的。它主要用于确保在容器中注册的映射不会影响容器中的更改,并且不会影响容器中的更改。与相应的控制器相处。LET对匹配方法的源代码lookuphandlermethod的源代码来看(),,
基本上,URL路径匹配基本上完成了。在这些方法中,进行了大量的准备和匹配处理,并且看起来非常复杂。在这里不再深处。
如果不存在相应的处理程序,则服务器将响应404个错误。
4.让处理程序找到相应的处理程序后,您需要
代码相对简单。初始化时,处理程序将加载以下三个处理程序:
在这里,通过supports()方法执行类型判断的实例,以选择相应的处理程序以进行后续处理。
5. LastModify缓存机制的下一个get或head请求,以下是一种称为LastModify的缓存机制。它的作用和实施逻辑也被充分理解。首先,当第一个请求成功时,服务器将响应响应标头的头部。ADDlast-modify属性,最后更新时间的值;当请求第二次访问时,您将调用getlastModify()方法以获取请求头中的if-modified-since属性,然后调用checkSotModify()方法检查服务以检查服务的服务,以检查终点的内容。在属性值之后更改,如果更改不更改,则响应304状态代码(仅返回响应头,否则内容将响应)。
6.拦截器的前后处理类似于春季的BeanPostProcessor。SpringMVC在这里提供了一个处理程序截距。对于处理程序的真实处理请求的逻辑,扩展一些请求可能很方便。
它提供了三种接口实现的方法。在开发中,我们可以通过实现此接口进行一些拦截处理来要求。
7.以前,我们在处理之前已经获得了相应的处理程序和一些准备工作,并且实际处理请求是由handle()方法完成的。在这里,您将在Apptracthandlmethodadapter中调用源代码。
发现特定的实现仍在子类请求mappinghandlerAdaptern的句柄内部()中
我们可以在此处看到会话会话的同步和缓存,但是我们主要关心调用InvokeHandLermet()来真正处理请求。如果您继续了解此方法的源代码,我们可以知道将首先将其带入方法的参数。执行工作和其他工作。最后,底层是调用控制器类和保存在我们之前的处理程序中的方法,这是我们自己实现的业务逻辑代码。
8.上面的处理呼叫已经完成,这将返回ModlandView。如果我们提供诸如JSON,XML和其他非页面视图模型之类的格式,则该MV等于NULL。最后,processDisPatchResult()方法将被称为deal,
此处的结果处理将分为两个步骤。首先是调用ProcessHandLexception()方法来处理处理请求逻辑中的异常。
我们可以看到,最终的异常信息和状态代码的末尾被写入客户端。
9.查看渲染如果当前请求处理结果返回ModlandView的存在,则将调用渲染方法以进行页面渲染
我们首先按返回视图名称,然后使用ViewResolver View Parser解析相应的视图,最后调用Render()将页面归还到页面,EL表达式中的JSTL语法或原始请求原始请求属性等将被解析。
最后,在此步骤中,SpringMVC中的呼叫过程处理已经完成。
作者:风流草
