SpringMVC的启动过程

共 2146字,需浏览 5分钟

 ·

2020-04-23 23:21


本文公众号来源:编程新说作者:编程新说李新杰本文已收录至我的GitHub

打成war包并放入Tomcat等Servlet容器下面运行的,都认为是SpringMVC传统的启动方式。

和SpringBoot连用且采用内嵌Web服务器并打成
jar包直接运行的,可以认为是SpringMVC现代的启动方式。

传统的启动过程

基于web.xml(配置文件)的方式启动肯定算传统的,但由于现在web.xml几乎已经绝迹,所以就不考虑它了。

与之相对的就是基于编程(写代码)的方式启动,流行于前几年的
SSM(Spring、SpringMVC、MyBatis)中。当然也算传统的。

通过一个“
小桥式”的接口ServletContainerInitializer(Servlet容器初始化器)把Tomcat的启动和初始化进程带到了SpringMVC里。

在这个“桥式”接口上可以指定“感兴趣”的类或接口,SpringMVC指定的是
WebApplicationInitializer(Web应用初始化器)接口,意图已经很明显,就是通过这个初始化器接口来完成SpringMVC应用的启动和初始化。

我们先来看下这个初始化接口,如下图01:

759cc307f4c1032f60e60c8586d6c6d9.webp


它只有一个onStartup方法,方法只有一个参数就是ServletContext,这个ServletContext由Tomcat创建好后提供给SpringMVC,SpringMVC在启动过程中调用这个onStartup方法,在这个方法内完成自身的创建和初始化,还要把Servlet和Filter等注册到ServletContext里。

这些工作都是SpringMVC要做的,而不是我们要做的,所以SpringMVC肯定已经实现了这个接口,我们查看下类型信息,如下图02:

df4811f531b75a8f5f0c13b99195a809.webp


我们发现了一个看着很重要的类,就是:

AbstractAnnotationConfigDispatcherServletInitializer

可惜这个类是抽象的,肯定是不能直接用的,但是它里面已经包含了刚刚上面提到的所有完整的启动逻辑过程。

如果你对SSM很熟悉或Spring的
官方文档看的很熟悉的话,你一定知道这个类是怎么用的。是的,我们需要定义一个类来继承它即可。

先看下官方文档上给的用法,如下图03:

327cfaed8942b4bfd2dbc5c75e3c8baa.webp


继承之后,我们需要提供三方面信息,一个是用于注册到根容器中的类,一个是用于注册到Servlet容器中的类,一个是核心Servlet的映射URL。

注意,这里说的容器指的是Spring的ApplicationContext这个容器,其中根容器和Servlet容器是父子关系,且在SpringMVC中核心Servlet映射的URL必须是“/”。

下面给出一个我在几年前为公司搭建框架时的代码,如下图04:

cc14e04f21d9c23439556b34183b3e8e.webp


这就是以编程的方式来完成SpringMVC的启动。我们自己定义的这个类就是前文提到的“感兴趣”的类。

这个类是
不用(或不能)向Spring容器注册的,因为这个类是感兴趣的类,所以Tomcat会从jar包里把它找出来,这样SpringMVC就拿到了我们定义的这个类。

其实最主要的是这时候根本还没有Spring容器呢,哈哈,因为Spring容器就是在这个类里才创建出来的,有点意思吧。

其实这个类里包含的内容非常多,我们都可以使用写代码的方式来进行配置。下面举几个示例。

比如对
核心Servlet的一些定制化设置,如下图05:

e5fa449503f0e39d806eee3506033fa9.webp


比如可以加进去一些自己需要的过滤器,如下图06:

987dca7c5dddd2a71c7b574f64cf520a.webp


比如可以对文件上传进行一些配置,如下图07:

4fd50f5a7f7ee2917038e16a88804da9.webp


当然,还可以介入到Spring容器的初始化过程中,进行一些额外的操作,如激活特定的Profile等,如下图08:

229b54d70ef47641414d019a9f7638dc.webp



启动过程中做的事情

其实前面已经说了一些了,这里再来个完整版的,主要包括的事情有:

1、创建根容器。

2、然后把根容器放入ServletContext中。

3、接着创建Servlet容器。

4、然后使用Servlet容器去创建核心Servlet。

5、接着把核心Servlet注册到ServletContext中。

6、接着再注册一些过滤器。

下面我们使用几张图把这些内容一个个展示一下,需要详细了解的可以去看看对应的源码。

创建根容器,可以看到是基于注解的容器类,如下图09:

fef5bb662d44104e55f56eaf8de4e28f.webp


将根容器放入ServletContext中,因为ServletContext在应用运行期间一直存在,所以根容器是一个全局性的,也一直存在,如下图10:

71fe6c9949f1f0addbee0094701a39a6.webp


创建Servlet容器,容器类也是基于注解的,和根容器类是一样的,如下图11:

67ac27ead7c08eac5590dbeefe785a67.webp


使用Servlet容器去创建核心Servlet,如下图12:

db7e5ce0b99a58dc4cf8c0ebbbe27061.webp


把核心Servlet注册到ServletContext中,如下图13:

8f6df50e5e2a55b35ac923a0472ea75b.webp


最后就是注册一些过滤器了,如下图14:

73dd8a68f63374809cd8a726e25d2a6c.webp


建议做Java开发且渴望优秀的朋友一定要把这些东西搞清楚


 各类知识点总结

下面的文章都有对应的原创精美PDF,在持续更新中,可以来找我催更~

扫码或者微信搜Java3y 免费领取原创思维导图、精美PDF。在公众号回复「888」领取,PDF内容纯手打有任何不懂欢迎来问我。

原创电子书
8f5dc5c6066c4c00c8c93766cb8e6710.webp

原创思维导图

684e7581ffe1e93da9a60e433ed8af16.webp


3c5d32ca28d2c2517e57cbc4ea76501a.webp

92d95ad090f9a0d7e311716cf5c6e00a.webp

92d95ad090f9a0d7e311716cf5c6e00a.webp

浏览 22
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报