前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot源码解析(九)- Servlet整合原理

SpringBoot源码解析(九)- Servlet整合原理

作者头像
写一点笔记
发布2020-09-27 09:57:03
6210
发布2020-09-27 09:57:03
举报
文章被收录于专栏:程序员备忘录程序员备忘录

在之前的学习中我们已经了解了SpringBoot得基本启动流程,但是到目前为止还有几个小问题。第一是基于后置处理器的注解解析得详细过程,getBean是如何调用BeanPostProcessors提供的接口的。还有SpringBoot是如何整合Servlet的。如果上述三个问题得到的解决,就我本身来说。我觉得SpringBoot得分析就已经可以初步结束,剩下的工作就是学习springBoot得基础组件比如jdbc、cache、mvn等内容。但是这只是目前的想法,至于在这期的解析中能不能发现新的疑惑目前还不得而知。现在就让我们开始解决这三个疑问吧。

在我们的content容器的中我们发现了Servlet的身影,但是我们并没有发现SpringBoot是如何整合的。

因为在ServletWebServerApplicationContext我们看到了servlet得身影,因此我们继续在这里查看这里是如何整合Servlet的。

在createWebServer中我们看到ServletContentInitializer。但是这里的servletContext是做什么?

通过一番跟踪之后发现这个servletContext其实就是空的

,而这里的getWebServer其实就是获取Servlet的启动器。在查阅了相关资料之后,我们发现在DispatcherServletAutoConfiguration中查找到了dispatcherServlet得踪迹。这里的又是如何将content整合进去的?

我们进一步跟踪到DispatcherServlet中。发现我们好像已经进入了mvc得模块了。

而DispatcherServlet的核心是content,那么这个content到底是何时注入的?在查看的时候并没有发现。但是我们发现了onRefresh方法。

但是在DispatcherServlet的父类FrameworkServlet方法中发现了一个OnApplicationEvent方法。这个方法是我们在发布spring监听事件的时候才注入的,也就是说当监听到事件的时候才初始化DispatcherServlet中至关重要的一些和content相关的组件。这样和合适,毕竟只有在springboot初始化结束之后才发布这个事件。

至此,我们大概明白了springBoot与DispatcherServlet的整合过程。首先在注解解析和getBean的过程中就将bean先注入的bean工厂的map中,在spring的bean都已经初始化完毕之后,springBoot发布初始化结束的事件。然后DispatcherServlet的的父类监听到之后调用DispatcherServlet的onRefresh方法初始化一大堆拦截器控制器等。

但是我们奇怪的是tomcat如何将dispatcherServlet整合到tomcat中的?通过debug我们发现在getwebserver的时候发现了DispatcherServlet的踪迹。

我们继续回过头来看这个方法;

在configureContext方法中设置了defaultServlet出来静态资源。如果设置了jsp得话,这里也会加入JspServlet。但是我们的DispatcherServlet到底是啥时候加入的?

加入之后,又是如何添加到tomcat中的?还是不添加了?

通过进一步debug发现在ServletContentInitalizerBeans方法中拿到了各种Servlet和Filter。

继续跟踪,发现这里通过类型将Servlet和filter逐个加入了initializers中。也就是这里1个Servlet和4个Filter得起源代码。

通过不断的debug我们发现在OnStartUp方法中将上述筛选出来的Servlet和Filter注册到了ServletContext中。

分析到这里,我们发现getWebServer传入的就是initalizers,这里的initalizers就是我们的servlet和filter了。这里有点小小的不解,因为上边的servetContext已经注册了initalizers了那么这里直接解析servertContext不是更好吗,为啥要原始的?

总之这块的逻辑就是将各种Servlet和Filter注册到tomcat中。我们之前的说的DispatcherServlet也是在这里注册进去的。但是逻辑比较复杂,我个人觉得还是依靠的servletContext进行的。这里就不进行分析了。总之这里的逻辑我们是清楚了。

总结:SpringBoot在OnRefresh方法中的createWebServer方法中获取了注册到IOC容器中的Servlet和Filter并注册到了ServletContext中,然后通过判断web服务器的类型创建web服务器。并将解析出来的ServletContext注册到web服务器中,在tomcat服务器中会创建DefaultServet和JspServlet等。在源码中我们发现SpringBoot支持三种服务器jetty、tomcat和undertow。在服务器启动成功之后,SpringBoot发布Spring事件,然后DispatcherServlet得父类监听到之后获取IOC容器然后获取content各种拦截器和控制器使得DispatcherServlet真正具有意义。

这里我们小小的猜测一下为啥传入的不是ServletContext而是Initializers得原因可能是要兼容这三种服务器吧。但是作为东家得SpringBoot会这么被动吗,不应该是别人来兼容自个么!代码分析到这里,您有没有明白这其中的原理?

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-09-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员备忘录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档