servlet到springmvc的演进
1.简单看看servlet
1.1.servlet继承关系
先看看下⾯servlet的这个继承关系,有点印象即可(可以暂时忽略ServletConfig,这个接⼝就是让我们可以从l⽂件中拿到标签中的参数,⽐如,等标签中的参数)
然后我们看⼀下最简单的servlet⽤法,概念和由来就不说了,说了我们也不懂,就知道能够通过浏览器访问servlet就够了。
1.2.servlet最简单的⽤法
新建⼀个myspringmvc项⽬,然后弄⼀下如下配置
可以了,就这么多,然后我们运⾏eclipse中集成的tomcat,在浏览器输⼊url就能访问了,很容易。
1.3.servlet⽣命周期
这个时候有个⼩问题,为什么我们发送⼀个get请求(在浏览器输⼊⽹址),就会直接跳转到get⽅法呢?这么智能的么,这么⽜?
所以我们要站得⾼⼀点的⾓度看servlet的⼤概结构,如下图,最重要的就是这三个⽅法,还有另外两个⽅法暂时忽略:
getServletConfig()是可以拿到l中配置的等标签的参数,还有getServletInfo()其实就是返回作者信息,版本信息等等,貌似还没⽤过。。。。。
servlet和tomcat的关系最重要的就是那三个⽅法,⼀般别⼈都把这三个⽅法叫做servlet的⽣命周期。(注意service⽅法的两个参数,没有实现HTTP协议)
到了这⾥,假如就给你这样⼀个接⼝,让你⾃⼰写实现类,你感觉怎么样?反正我是很绝望的,不知道从哪⾥下⼿,这么多功能要实现,⾃⼰⽔平⼜⽐较菜,怎么编写⼀个完全的servlet实现类呢?
于是啊,⼀个抽象类就出来了GenericServlet,这个抽象类实现了Servlet接⼝,把⼏乎所有的⽅法都给你实现出来了,⽐如获取servlet上下⽂,获取initParameter等等常⽤的功能,就留下了那三个⽣命周期⽅法init(), service(),destroy()没有实现,这就需要我们⾃⼰去实现类,所以我们可以继承这个抽象类,实现这三个⽅法就ok了。
但是啊,我还是有点不会,因为我是⽤过浏览器发请求过来啊,你这个service⽅法要⼲嘛呢?主要逻辑是什么啊?⽽且每次都要实现这三个⽅法,好⿇烦的啊,因为还要判断是get还是post⽅式提交,再调⽤get或者post⽅法,⽽且都是重复的东西,有点不会。
终于,出来了⼀个⽐较全⾯的抽象类HttpServlet,这个类继承了GenericServlet,还实现了http协议,其中做的最主要的是就是将那service()⽣命周期⽅法给实现了,并且在这⾥会根据浏览器提交过来数据的⽅式,给分发到各⾃的⽅法去实现,⽐如分发到
doGet(),doPost()等,简单看⼀下源码
后⾯还有post,put,delete⽅法的判断,跟这⾥⼏乎⼀样,⽽且在本类中已经定义了doGet(),doPost()等⽅法,⼏乎没有怎么实现,所以啊,我们只需要继承HttpServlet类,根据我们的请求⽅式实现doGet(),doPost()等⽅法就可以了,分⼯明确,⽤起来也很舒服。
⽽且这⾥新⼿可能有点头晕,为什么会调⽤我们实现的doGet,doPost⽅法,⽽不是⽗类中的那些doXXX()⽅法呢?其实啊,这⾥⼜是⼀个基础知识,⽐如⼦类B继承⽗类A,重写⽗类⽅法aa(),那么实例化⼦类之后(这⾥就是多态的⽤法),调⽤aa()⽅法肯定是先在⼦类中有没有aa()⽅法,有的话就调⽤⼦类的,没有的话就调⽤⽗类的!应该在java基础的时候这种问题贼多,坑了很多新⼈。
到这⾥Servlet的⼤概轮廓就清楚了,我们再来看看最上⾯的那个截图,是不是觉得懂了⼀点点了
2.简单看看springmvc初始化过程
还记得最开始学习springmvc的时候是⾃⼰看视频学习的,刚开始有很多的问题不懂,要⾃⼰慢慢理解,然后⼤量的查资料,记得⽐较清楚的⼀句话是说:springmvc中那个前端控制器其实就是⼀个servlet,springmvc的本质就是⼀个servlet!
反正我是牢记这个概念,哦哦,原来springmvc本质就是⼀个servlet啊,然后我就放着不管了,也不是怎么懂,反正我springmvc⽤的贼熟练。不就是那⼏个处理器吗?前端控制器,处理器映射器,处理器控制器,controller,视图解析器,我经常简单的这么⼀配置,就可以⽤了,然后和spring⼀整合,ok了!
2.1.springmvc和servlet的关系
⾸先问⼀个问题,为什么前端控制器是⼀个servlet啊?难道也是继承了HttpServlet吗?其中⼤概的流程是怎么样的呢?总感觉很模糊,似懂⾮懂。
那么我们就先来看⼀个前端控制器(DispatcherServlet)的继承结构(混个眼熟):
上图很明显,有三个新增的类,分别是HttpServletBean,FrameworkServlet,DispatcherServlet;这
三个类我第⼀眼看过去反正我是不知道⼲嘛⽤的,就⼤概知道最后那个前端控制器,所以我们就慢慢的来看看前⾯两个类是⼲嘛⽤的啊?把前⾯两个弄清楚了,就差不多了。
2.2.随便看看HttpServletBean,FrameworkServlet
对于HttpServletBean,我们先回忆前⾯的servlet的内容,在HttpServlet总只是实现了service()⽅法并在其中做了⽅法分发,但是servlet⽣命周期可是有三个⽅法啊,还有init()和destroy(),于是我们在这⾥就会⽤到init⽅法了;
这⾥会重写GenericServlet的init⽅法(其实就是重写HttpServlet的⽗类GenericServlet的init⽅法)
由于这个initServletBean()⽅法是⼀个空⽅法,肯定是留给⼦类去实现的,然后我们去FrameworkServlet中还真的到了这个initServletBean()⽅法。
这⾥就是⼀个⽐较重要的地⽅了,稍微截⼀下initServletBean()⽅法中的代码:
注意:⼤家知不知道springmvc+spring整合的时候,会有⽗⼦容器的概念!⽗容器就是ioc容器,启动toncat就会被l中的那个监听到,⽴马就会创建ioc容器,⾥⾯放的是service,dao,以及其他的各种bean;这⾥的⼦容器是springmvc的容器,⾥⾥⾯放着web层的所有组件,处理器映射器,处理器适配器,视图解析器,controller等;
还有我没有记错的话,由于⽗容器先创建,⼦容器后创建。所以⽗容器的引⽤会保存在⼦容器⼀份,所以可以通过⼦容器获取⽗容器的实例,然后再获取其中的bean;
在initWebApplicationContext()⽅法中,其实就是对spring ⼦容器的创建以及刷新,这⾥就随便提⼀下,不深⼊了!我们只看其中的刷新⽅法:
你点开刷新⽅法你会发现这⼜是⼀个空⽅法,等着⼦类去实现的!不知道⼤家到这⾥有没有看到⼀个很有趣的逻辑,就是很多时候,⼀个类中有些⽅法⾃⼰是不会去实现的,⽽是要留给⼦类去实现,哈哈哈!⼦类假如会说话,肯定会说:我真是⽇了狗哦!
2.3.继续随便看看DispatcherServlet
终于到这个类了,前⾯说了这么多,都快睡着了。。。
由上⾯可以知道,DispatcherServlet中肯定要实现那个刷新⽅法,于是我们就直接到这个刷新⽅法看看到底是什么⿁!
可以看到初始化了好多组件,注意⼀点:这⾥的context是⼦容器。
3.springmvc处理请求
前⾯springmvc初始化说了这么多,其实就是将⼦容器创建,然后初始化了那9个组件放进去就ok了,那么接下来就说说怎么处理⼀个请求吧!
还记得前⾯说处理请求,也就是我们在浏览器输⼊⽹址,⼀点回车,就会执⾏相应servlet的service()⽅法吧!
在HttpServlet中的service()⽅法中接收请求,根据请求⽅式(Get,Post等)分发到相应的doGet(),doPost()等⽅法,然后我们在FrameworkServlet中会发现,这个类将这些service和doGet(),doPost()等⽅法都重写了,是个狠类啊!
我们就来简单看看FrameworkServlet中的⽅法执⾏流程吧,不细看源码!
打开doGet⽅法,发现也是到processRequest()⽅法中
我们继续往processRequest()⽅法看:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论