SpringMVC大致过程
MVC
MVC是一种框架模式,将M和V的实现代码分离。
- M(Model):模型,业务规则。处理请求、返回数据,数据可以被多个视图使用。
- V(View):视图,就是你能看到并能交互的界面。
- C(Controller):控制器,负责接收用户的请求去调用哪个M去处理,然后再返回确定哪个V显示数据。
Servlet
为什么在这里讲一下Servlet?其实SpringMVC就是一个Servlet,所以弄清楚Servlet的过程,SpringMVC的就类似了。
我们现来看一下Servlet的类图关系。
SpringMVC
SpringMVC和Servlet的关系
大致过程
- 初始化的时候用了一个Map保存URL和Controller类的对应关系
- 根据请求的URL找到对应的Controller,然后从Controller中找到处理请求的方法
- 将请求参数绑定到方法的形参上,执行方法处理请求,并返回结果视图
九大组件
在DispathcherServlet类中,我们可以找到SpringMVC的九大组件。
1 |
|
源码解析
SpringMVC初始化
首先我们从Servlet的初始化init()开始,在DispatcherServlet类中,我们并没有发现Servlet的初始化方法,所以我们去父类中去找找。在HttpServletBean中我们终于发现了init()方法。
我们可以看见这里只是对一些初始的属性参数进行了设置,具体通过子类调用initServletBean()这个方法来调用。我们点进去看看
我们可以看到子类FrameworkServlet的initServletBean()方法中添加了一些日志相关的信息,以及一个重要的方法**initWebApplicationContext()**,这个方法最终会调用我们IoC容器的refresh()方法。剩下的initFrameworkServlet()这个方法是个空方法,可以留给我们进行扩展。我们继续跟进initWebApplicationContext()方法。
我们进入createWebApplicationContext()方法中
configureAndRefreshWebApplicationContext()方法,终于我们看见了refresh()方法
其实就是IoC容器的初始化。
我们接着看SpringMVC九大组件的初始化
在DispatcherServlet中,onRefresh()方法和initStrategies()方法
到此,SpringMVC初始化差不多就完成了,下面去看看SpringMVC是如何处理请求的。
SpringMVC处理请求
在doService()方法中。其中最核心的方法是doDispatch()方法。
我们进入doDispatch()。
这里面的处理大致流程是:
- 先判断一下是不是文件上传
- 通过getHandler()方法找到请求对应的处理handler的Bean实例以及添加一些拦截器,封装成一个HandlerExecutionChain请求处理链对象
- 获取一个支持的处理适配器HandlerAdapter。getHandlerAdapter()
- 调用给定的handler处理请求,执行并返回结果视图。handle()
- 处理一下处理的结果,可以是ModelAndView或者是一个异常。processDispatchResult()
我们先去看看getHandler()方法。
继续点进去,在AbstractHandlerMapping的getHandler()方法中。
是不是看见了一个我们很熟悉的方法?getBean()。这时候我们就获取到了对应handler的实例了,然后就是调用getHandlerExecutionChain()方法,将一些拦截器与之封装为一个HandlerExecutionChain。
这时候一个HandlerExecutionChain就完成了。
然后我们去看看getHandlerAdapter()方法。
接下来是handle()方法,我们点进去看看,他会调用AbstractHandlerMethodAdapter类的handle方法,我们会发现它最后会调用handleInternal()这个方法,交给子类去实现。
进入handleInternal()方法
我们可以看见都会调用invokeHandlerMethod()这个方法,跟进去。都是些什么addXXX、setXXX、registerXXX方法。最重要的是invokeAndHandle()方法,它完成了将请求中的参数和方法中的参数进行绑定,通过@RequestParam注解或者是ASM框架。
invokeAndHandle()方法
然后就是返回相应的ModelAndView了。
接下来对ModelAndView进行处理,在processDispatchResult()方法中。可以看见对异常的处理和对正常视图的处理。
其中调用了render()方法对视图进行渲染。
到此,一个请求的处理差不多就完成了。SpringMVC的工作也差不多结束了。其中还有些细节的地方,比如在将请求中的参数和方法的参数绑定时ASM框架的使用,感兴趣可以去看看。
关于调用了refresh()方法,九大组件什么时候初始化。
前面我们知道看初始化的时候,如果进行了refresh(),下面的onRefresh()方法好像就不能调用了啊,那九大组件到底是什么时候初始化的呢?
这其实用到了事件监听器。我们都知道IoC容器的refresh()方法中有事件传播器的注册(initApplicationEventMulticaster()方法)、事件的发布(finishRefresh())方法。其实就是在事件发布的时候,调用了SpringMVC九大组件的初始化。我们后续再讲。
SpringMVC大致过程