认识SpringMvc
认识SpringMvc
SpringMvc
是基于spring
在web
领域进行开发的框架,使得业务开发者无需关心Servlet
组件的逻辑处理,让业务开发者仅需要关心业务逻辑的处理。
由于在我较为整体的学习SpringMvc
源码时,市面上已经比较倾向于前后端分离的开发模式,已经少有这种传统的jsp
的模板结构的模式了。所以基本上只会记录从请求到前端控制器DispatcherServlet
以及HandlerMapping
、HandlerAdapter
等的处理,并不会记录视图解析器等与视图相关内容。
以下先简单罗列后续会比较重点介绍的部分。
DispathcerServlet
:前端控制器,实际是它就是一个servlet
。若你学过最原生的写法,不依赖于任何mvc
框架,应该是继承一个HttpServlet
后,重写它的service
方法,然后再通过请求方式的不同等进行不同的路由跳转或者重定向等操作。实际上DispatcherServlet
也以此为主要逻辑,它就是控制请求的分发。Handler
:处理器(具体的业务逻辑),在项目启动时会将@Controller
中的一个个@RequestMapping
方法都抽象为这个接口的结构。HandlerMapping
:处理器映射器,当请求来临时,根据请求的url
等结构,寻找具体的Handler
。HanderApdater
:处理器适配器,会将Handler
包装为处理器适配器,从而支持多种类型的处理器,通过它根据适配的结构调用正在的处理器的业务逻辑方法,完成功能处理。
1. spring、springmvc、springboot间父子容器的问题?
对于传统的springmvc
项目而言,可以通过web.xml
文件配置来配置
仅配置了
<servlet>
(DispatcherServlet
)。这时在启动项目时,在对DispatcherServlet
进行初始化时,调用父类FrameworkServlet
的initWebApplicationContext
方法,在该方法中的设置父容器,是获取不到spring
容器的,所以这种情况下整个项目仅有springmvc
容器。若配置了
<listener>
(ContextLoaderListener
)和<servlet>
(DispatcherServlet
),这时项目启动时,先通过监听器加载spring
容器,待完成spring
容器加载后,才会通过DispatcherServlet
进行springmvc
容器的加载。(为什么在加载spring
容器的过程中不会加载DispatcherServlet
:这时spring
并不会识别到DispatcherServlet
),在springmvc
容器加载时,可以获取到spring
容器,并设置为springmvc
容器的父容器。仅配置
<listener>
(ContextLoaderListener
),这种情况就没得说了,如果不加载DispathcerServlet
那根本就不是springmvc
项目。
注意:以上第二种情况,需特别注意若是使用中出现事务、或者AOP
等处理,需保证父子容器中都有对应的处理。
springboot
是如何处理springmvc
中的父子容器问题?
我认为springmvc
的这种父子容器思想(子容器可以访问父容器,父容器不可访问子容器),是可以有效的进行框架层级边界的划分,比如service
层一般放在spring
容器中,而web
层(controller/Action
)等放在springmvc
容器中,所以如果需要跟换web
层框架,比如将springmvc
更换为struct
,仅仅只需要将spring-servlet.xml
文件替换为struct
的配置文件即可。
在springboot
中,并没有延续springmvc
的这种父子容器思想,从设计结构来说,DispatcherServlet
的父接口中有ApplicationContextAware
接口,也就是说,如果在spring
容器初始化过程中,将DispatcherServlet
识别为bean
,那么就会通过后置接口为DispatcherServlet
设置容器,所以真正调用DispatcherServlet
的初始化方法时,this.webApplicationContext
已经通过后置接口赋值,就就不会重新创建一个新的容器,springboot
就是通过这种方式,来控制整个上下文仅使用一个容器。
2. springmvc和servlet之间的关系?
web
端开发实际上就是客户端和服务端进行交换数据,而交换数据的过程中不可避免的需要经过建立连接、传输数据、业务逻辑处理、返回数据、关闭连接的过程。而在日常开发过程中,业务开发者并不需要关心整个过程,业务开发者只需要关注业务逻辑处理这一环节。这是因为tomcat
处理了这些动作。
在springmvc
中,通过web.xml
配置文件来配置DispatcherServlet
。
1 | <servlet> |
实际上DispatcherServlet
就是一个servlet
,这个配置文件配置了DispathcerServlet
这个Servlet
需要拦截的url
地址,显然这个配置的是/
,也就是入站的所有地址。也就是说当客户端发起请求时,先进入tomcat
,由tomcat
为其建立连接后将请求等信息传递给DispatcherServlet
这个servlet
。由这个DispatcherServlet
来处理请求的分发,在SpringMvc
中称它为前端控制器。