一、摘要
之前review了下java web helloworld的程序,梳理了一波java web基础之后,发现对spring的基本原理机制有些遗忘,故花了一些时间对springmvc的核心机制进行一次review。本文由浅入深,从手写的servlet的程序开始,逐步阐述spring mvc的运行机制和原理
Hellworld wiki:juejin.cn/post/684490…
servlet程序代码仓库:github.com/venusforest…
二、手写servlet web程序
这一节我们尝试抛开IDE工具,手写一段web程序,并在tomcat下运行
- 编写controlller代码,并编译

- 配置web.xml,并在tomcat下运行
把上面的class文件copy到tomcat/webapps/ROOT/WEB-INF/classses/目录下,并在web.xml文件下添加映射关系


三、servlet与tomcat
从上述简单实例,可以看到我们编写的HelloWorld类继承了HttpServlet类,并且实现了init、doGet、destory方法,用户在浏览器发送请求的时候,tomcat会根据web.xml配置,找到HelloWorld类,并把用户请求打包成HttpServletRequest,交给doGet方法进行处理,之后返回HttpServletResponse。
servlet规范
实际上,servlet-api是sun公司在90年代制定的web开发标准,tomcat实现了servlet规范,对用户的请求进行打包,这样业务方在编写代码的时候只需关注HttpServletReques输入和HttpServletResponse输出,简化的web开发流程。

上图是w3cschool介绍servlet的截图图,tomcat相当于左边的serlvet容器,类似的容易组件还有JBOSS,Jetty,右边的Servlet是业务方实现servlet接口的业务类,在tomcat启动和关闭的时候后,会调用init和destroy方法,进行初始化和销毁,httpServlet的service方法会根据get、post等请求,调用业务方实现的doGet、doPost方法
war包与tomcat
war可以理解为可以被tomcat识别的压缩包,与jar对应。将war放在tomcat的app目录下,tomcat启动时会将其解压,并启动war下的servlet实例。
将hellworld程序通过maven编译好的war,copy到tomcat中,启动运行如下图所示


四、spring mvc启动流程与机制
了解servlet和tomcat基本原理和操作之后,我们基于之前的helloworld分析一下springmvc的运行机制.
如下图所示,helloworld中的web.xml主要分为三部分,context-param、listener、dispatcher

- context-param主要配置servletContext参数,这里面指context config文件applicationContext.xml。在这个xml里面可以以bean组件的形式配置业务sevice类、数据库driver、orm组件如mybatis等,spring会把xml文件里的配置,在启动时加载到ioc容器中,这样业务代码可以根据需要从ioc容器中读取或者克隆实例,而不需要手动new对象。helloworld示例比较简单,没有配置任何bean
- listener其实也是servlet的规范标准,ServletContextListener接口定义了contextInitialized、contextDestroyed两个方法,如果配置了自定义listener类。tomcat启动时和关闭时会执行上述两个方法。helloworld中使用了spring的ContextLoaderListener





- 根据上面讲述的servlet运行机制,可以看到dispatcher实质上也是一个servlet,处理来自客户端的所有请求,然后分发的对应的controller进行处理。下面看看dispatcher servlet启动加载流程
通过下面类似,可以看出dispatcher和httpservlet的层层继承关系。dispatcher的初始化流程也应该从servlet-api规定的init的方法开始。

Dispatcher init方法执行的是父类HttpServletBean的init方法,然后执行initServletBean

initServletBean执行的是Dispatcher 另外一个父类FrameworkServlet的initServletBean方法,Dispatcher也会调用initWebApplicationContext方法创建自己的applicationContext,并把contextLoader创建的xmlWebApplicationContext设置为根context,这样设置的好处是dispatcher可以访问xmlWebApplicationContext共享的bean,本示例没有涉及到

Dispatcher context创建过程中,会调用onRefresh方法,初始化handlerMapping,handlerMapping的作用就是将用户请求的url和controller代码关联起来



defaultStrategies配置在DispatcherServlet.properties文件中


五、spring mvc处理用户请求流程
当收到客户端请求是,tomcat调用dispatcher对象的doService方法,然后从上述handlerMapping找到相应的handler处理请求


六、总结
springmvc主要作用通过对servlet的再次封装,通过注解、反射、装配等机制,简化的程序员的码量,通过编写更为简单的controller代码,实现自己的业务逻辑
本篇主要针对之前的helloworld程序,初步探究了Spring mvc原理机制,实际还有更多丰富的功能,希望有机会抽时间再进行阅读