SpringMVC源码分析

Pogx原创,未经允许,请勿转载!!!

springMVC是一个建立在spring框架基础之上的一个web层框架,它负责发送每个请求到合适的处理程序,使用视图来最终返回响应结果的概念。

 

SpringMVC最重要的一个类是DispatchServlet这个类,当我们打开这个源码,感到一脸蒙蔽。但是坐下来冷静一下看看,发现,这个东西竟然继承了一些类

跟过去看看

好像也没啥线索,继续跟

这时有了重大发现,发现这个DispatchServlet终归结底还是继承了HttpServlet,那么我们就可以按照普通的servlet的生命周期来分析它了。

Servlet的生命周期大家都还记得吧,不记得没关系,我来简单列一下

1.首先tomcat启动的时候会去查询web.xml中的配置文件找到servlet的配置,然后会通过java反射机制创建这个servlet的实例。

2.     然后调用这个servlet的init方法去初始化,然后把这个servlet放入容器中管理,等待使用。

3.     当容器关闭时,tomcat会调用这个servlet的destroy方法来做一些善后工作。

Ok,下面我们就找init方法吧,看看这里面都干了些什么吧

这里面没有什么太复杂的逻辑,就是把配置DispatchServlet配置参数加载到内存中,以供spring使用。有的小白朋友就问了,什么参数。来张图你就明白了

然后主要就是这里面调用了initServletBean方法,这个方法在这个类中是空的,而它的子类实现了它,springmvc中用了很多类似的设计模式,叫模板方法模式。简单讲就是在父类中写好,你要调用哪些方法,我在子类中去实现,这样就按照了父类的逻辑顺序调用了相应的方法,而且子类可以有不同的实现。

好,下面我么就找哪个子类实现了这个initServletBean方法吧,跟我走。。。

看看这个HttpServletBean的继承体系如下

先找FrameworkServlet

我们寻寻觅觅,果然没猜错,方法的实现,写在了子类,而且还不少,我来分析下吧


略过日志记录往下走

调用了当前类中写的一个方法initWebApplicationContext方法,这个方法就很重要了,坐下来,喝杯茶,慢慢品尝spring这道美味可口的大餐。

先把源码粘上来,

第一步spring通过工具类获取父级WebApplicationContext容器,有的朋友问了,这个父级容器哪来的,何时创建的呢?给大家看看

 

就是在这个监听器运行的时候创建的,我们知道web服务器启动的时候,3大组件的创建顺序是Listener>Filter >Servlet。

所以这里是可以获取到父级容器的。当然也可以获取不到这种情况就不讨论了,因为,不可能说你用springMVC而不用spring框架的。

这里有几个if判断,我已经标号了,给大家分析一下执行流。

首先webApplicationContext一定是空的,为什么,因为你刚启动,肯定是空的。所以第一个if暂时不会执行。进入到第二个if了,这里调用了findWebApplicationContext,其实这里也会返回一个null,从这个findwebApplicationContext名称就知道,它只查找并不创建。把源码附上,大家看看

因此wac还是空的,所以进入第三个if语句,我们进到createWabApplicationContext方法中一探究竟。

这里的1号代码块中是日志,2号代码块中式判断的,3号代码块是创建一个可配置的web应用上下文,也就是web容器,4号代码块是初始化一下这个容器。比如设置之前的rootContext为父级容器。

最后把这个创建的容器返回,至此,我们的springMVC容器就这样诞生了。但是还没结束,在FrameworkinitWebApplicationContext()方法里还有if,我把它粘上来

接着之前的if序号编号

看看这个字段的初始值  

所以这个onRefresh()方法是要执行的,跟进去发现空实现,意料之内的事啦,没关系的,模板方法模式嘛,找子类,有线索,

这个方法又调用了一个initStrategies(。。)方法,这个方法干了什么勾当 ,跟进去看看

这里我直接加上注释了

这里我就只跟一个进去看看吧,initMultipartResolver(context),进去看看

注意我画线的这个段代码,大家考虑有没有问题啊,仔细思考哦

当然有问题,我们又没有在容器中注入这个解析器,它怎么能get到呢,出鬼了。

嘻嘻 不用着急,肯定是有原因的啦,我们翻翻DispatcherServlet源码,大家快看这里

这个静态代码段,会加载org.springframework.web.servlet.DispatcherServlet.properties这个文件,然后创建这个文件中定义的类我打开这个文件给大家米一眼

看到这里springmvc容器基本上初始化就完毕了,接下来就可以使用了,不不还有一个if,第7个if,大家忘了没有,直接简单说下这个if的所用吧,就是把spirngmvc的容器放到ServletContext下,我们可以获取到这个容器的引用。

一条线的往下走可能大家都忘了回去的路了吧,嘻嘻,执行栈结束,回到之前的调用方法initServletBean中


这里这个initFrameworkServlet方法同样是一个模板方法,在当前类中是空实现。在其子类中实现,好,我们接着跟进去,

看看DispatcherServlet中有没有initFramworkServlet方法,很遗憾,没找到。。不过这也正常。不实现就不实先嘛。好了,调用栈到底了,可以按顺序返回了。大家应该都忘了之前的调用顺序了吧。没关系,我记得呢,哈哈
这里我直接用类点类名的方式来定位这个方法
HttpServlet.init()FrameworkServlet.initServletBean()FrameworkServlet.initWebApplicationContext()&&FrameworkServlet.initFrameworkServlet()FrameworkServlet .createWebApplicationContext
调用栈就是这样,好了,有的朋友就问,那下面呢?

下面这个servlet就可以服务了呀,因为它已经被tomcat创建出来了,然后init()方法也执行完了,tomcat就会把这个DispatcherServlet放入tomcat容器中,等待请求的到来。


上面内容分析了springmvc容器的创建过程,下面就来详细分析一下,springmvc是如何那般处理请求的。
欲知后事如何请听下局分解,给大家留个悬念吧,或者自行思考,一下

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值