Servlet和HttpServlet解析-01


一个servlet应用,通常会包括两部分:容器和servlet应用。既然在研究SpringMVC源码,那么大家肯定知道servlet容器了,常见的就是tomcat;servlet应用呢,就是我们写的代码。我们需要把自己的代码部署到tomcat中运行,才能正常提供服务。

一个请求的流转大体上如下图:
Request

  1. 用户发送的请求,先被容器收到
  2. 容器把请求传递给servlet应用
  3. servlet处理请求,生成一个Response
  4. servlet将Response传给容器
  5. 容器将Response返回给用户

第一个发现:
通过上面的流程,大家可以看出,容器和servlet应用之间,是有通信的,也就是调用。我们知道,两个组件之间通信,肯定要遵循一个共同的协议,也就是一个规范,才能相互识别通信的内容。鸡同鸭讲,就是这个道理,语言不通肯定讲不明白。那么servlet应用和容器之间的语言,也就是通信规范,是什么呢?就是servlet规范。

所以,这个servlet规范,如果你有兴趣,可以读一读:Servlet规范

第二个发现:
整个流程,除了第三步处理过程外,其他的流程几乎都是固定的,第三步就是我们的业务逻辑,是根据需求来定制的。所以我们可以把第一二四五步抽象出一个组件来方便大家使用,不需要每个人都自己实现一遍,这就是容器;然后第三步的业务逻辑让用户自己定制。这个像什么?是不是很像设计模式中的模板?这里可以看做一个模板的设计模式。ps:我们没法知道当时各位前辈的想法了,但是通过现有的东西,我们可以反推一下。

第三个发现:
既然我们抽象出两个组件,那么这两个组件之间也设计了一个规范,怎么实现呢?servlet规范中规定了几个方法,双方约定,容器会调用init方法,创建servlet;调用service方法, 把用户的请求传递给servlet应用处理;移除servlet服务的时候,调用destroy方法销毁servlet等等。那么,容器和servlet应用只要使用同一个接口就可以搞定了。

接下来,我们看看这个容器和servlet应用的公共接口:Servlet
servlet

其实没啥,就是按照约定,定义了几个方法。init和destroy是生命周期方法,service是处理请求的方法,getServletConfig是获取servlet配置信息,getServletInfo是获取当前servlet信息,比如作者,版本,版权等等。

我刚开始学习web编程的时候,先学习用原生的servlet来写代码,最后学框架。但是,大家回忆下,我们是继承了HttpServlet,而不是Servlet。

大家看下HttpServlet的继承关系:
HttpServlet

ServletConfig:这个接口抽象的是servlet的相关配置,比如我们定义的servlet名字等等。它是创建servlet的入参,也就是说容器在创建servlet的时候,会把servlet的配置传递进来,传的就是ServletConfig的实现,通过这个接口定义的方法,能拿到servlet的配置。如果你在写代码的时候需要用到servlet配置,那么可以通过调用ServletConfig的方法拿到。

Servlet:这个接口里定义的servlet规范中约定的方法,上面说过了。

GenericServlet:这个抽象类很有意思,它实现了ServletConfig和Servlet接口,然而它是抽象的,是一个不能实例化的servlet。为什么要抽象一个这个?答案有点狗血,是为了让你写servlet省事点!(源代码中的注释就是这么说的!)它把两个接口的方法聚合在一起,然后提供了一些默认实现(比如,log,init,destory等等)管理生命周期,实现ServletConfig接口是为了在servlet中可以拿到servlet配置。然后我们只要重写service方法就可以了,其他的不需要关心,相当于提供了一个通用的,协议无关的模板给你,是为了可以实现一个通用的servlet,前辈们想的周到不周到?为了我等菜鸟真是操碎了心!当然这个层次的抽象我们还是不能直接使用的,仍然非常的简陋。

HttpServlet:这个就容易理解了吧,是http协议的servlet实现,相当于又给我们提供了一个http协议的servlet模板。我们最常用的就是http协议了,然而http协议有很多请求方法(get,post,put等等),HttpServlet将各个请求方法拆分了出来,我们只要继承HttpServlet,实现需要用的请求方法就可以了。又是前辈们在帮我们省事,你不需要非常精通http协议,就能实现你的业务逻辑了。说道这个类,大家应该都学过,最原始的servlet web应用,继承它,实现doGet, doPost方法,就能提供服务了。

学习到这里,相信大家都理解了整个从Servlet到HttpServlet的设计意图:一方面就是前辈们在给我们庖丁解牛,给我们铺路,提供便利;另一方面就是这种设计非常灵活,对于不熟悉的人,你可以立即上手实现业务逻辑。对于熟悉的人,你可以各种自己定制实现你的想法。

总结起来这么设计的目的就是几个词:灵活,解耦,方便。


文章作者: 枫山别院
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 枫山别院 !
  目录