Servlet是一个java编写的程序,此程序是在服务器端运行的,是按照Servlet规范编写的一个
java类。Servlet是处理客户端的请求,并将处理结果以响应的方式返回给客户端。Servlet框架
是怎样的呢?它的生命周期又是什么情况呢?这是本文需要探求的。
Servlet框架
网上下载Servlet源码,解压之后发现其由两个包组成:
1、javax.servlet
2、javax.servlet.http
javax.servlet
此包中定义了所有Servlet类都必须实现的接口或类。
接口定义:
ServletConfig接口---在初始化过程中由Servlet容器(Tomcat调用)
ServletContext接口---定义Servlet用于获取容器信息的方法
ServletRequest接口---向服务器请求信息
ServletResponse接口 ---响应客户端请求
Servlet接口---定义所有的Servlet必须实现的方法
类定义:
ServletInputStream类 --- 用于从客户端读取二进制数据
ServletOutputStream类 ---用于将二进制数据写入到客户端
GenricServlet--- 抽象类,定义一个通用的,独立于底层协议的servlet。
java.servlet.http
此包中定义了使用HTTP通信协议的所有Servlet类应该实现的类、接口。
接口定义:
HttpServletRequest接口 --- 封装http请求
HttpServletResponse接口 --- 封装http响应
HttpSession接口 --- 用于表示客户端存储有关客户的信息
HttpSessionAttributeListener接口---实现这个监听接口,当用户获取Session的属性列表发生
改变的时候得到通知。
类的定义:
HttpServlet类 --- 扩展了GenericServlet的抽象类
Cookie类 --- 创建一个Cookie,Cookie技术,用户存储服务器发送给客户端的信息。
通过阅读Servlet框架源码,其主要的框架结构如下图:
Servlet工作过程
通过上述Servlet框架的了解我们可以初步描述一下Servlet在Tomcat容器中是如何工作的。
来看下面的时序图:
1、Web Client 向Servlet容器(Tomcat)发出Http请求
2、Servlet容器接收Web Client的请求
3、Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中
4、Servlet容器创建一个HttpResponse对象
5、Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse
对象作为参数传给 HttpServlet对象
6、HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息
7、HttpServlet调用HttpResponse对象的有关方法,生成响应数据
8、Servlet容器把HttpServlet的响应结果传给Web Client
Tomcat和HttpServlet是如何进行交互的呢?从源码中我们可以得到
Servlet生命周期
在Servlet框架中所有的Servlet类都必须实现Servlet这个接口。其中定义了三个方法:
1、init方法:负责初始化Servlet对象。
2、service方法:用于响应客户端的请求
3、destroy:销毁Servlet对象,释放占用的资源。
Servlet生命周期四个阶段:
● 加载阶段:加载并实例化(创建Servlet实例)
● 初始化阶段:调用init()方法
● 响应客户请求阶段:调用service()方法,doGet、doPost
● 终止阶段:调用destroy()方法
加载阶段
Tomcat从文件系统,远程文件系统或其他网络服务中通过类加载器来加载Servlet,并调用
Servlet的默认构造方法(不带参构造器)
初始化阶段init()方法
当Servlet容器启动时:读取web.xml配置文件中的信息,构造指定的Servlet对象,根据配置
文件的信息创建ServletConfig对象,并将其作为参数传递给init方法进行调用。
Tomcat启动后:用户首次想某个Servlet对象发送请求,Tomcat会判断内存中是否存在指定的
servlet对象,如果没有则会去创建它,然后创建HttpRequest,HttpResponse对象,调用service
方法处理用户的请求。
从Servlet的构造开始我们没有显示的看到init()方法的调用,那么init方法到底是何时进行调用
的呢?阅读源码可以知道:init方法是在实例化Servlet之后调用的,其参数ServletConfig是在
Servlet初始化阶段Tomcat根据web.xml配置信息,和操作系统的相关环境生成并传递给init
方法的。
响应客户请求阶段service方法
service()方法是在客户端第一次访问servlet时执行的,其实init方法同样也是在有客户端访问
servlet的时候才被调用。不过需要特别注意的是讨论init方法在session级别上时,当存在不同的
会话访问相同的servlet时,Tomcat会开启一个线程处理这个新的会话,但是此时Tomcat容器
不会实例化这个servlet对象,也就是有多个线程在共享这个servlet实例。换句话说Servlet对象在
servlet容器中是以单例的形式存在的!然而查看其源码可以发现,Servlet在多线程下并未使用同
步机制,因此,在并发编程下servlet是线程不安全的。
对于Servlet的并发,线程安全的处理问题,笔者会找个时间好好的整理下思路。
对于不同的session访问相同的serlvet对象,只有一次init的过程,笔者会在接下来予以演示。
阅读HttpServlet的源码可以知道,基于Http通信协议的HttpServlet在进行客户端响应处理的
时候根据客户端请求,响应的类别不同分别调用不同的方法,其中最常用的就是doGet、doPost
方法,这两个方法是我们在编写Servlet中的主要的逻辑处理阶段。
终止阶段:destroy()方法的调用
上面的探讨中知道的了Servlet是如何加载、初始化、处理客户端的请求响应的,那么Servlet
在什么时候终止呢?其生命周期又是在什么时候结束的呢?
我们知道的是Servlet生命周期是有Tomcat容器来管理的,由此在Tomcat关闭、或者Restart
的时候,servlet的生命周期必然结束,destroy方法也必然被调用过。在客户端与服务器的一次
Session会话中,session关闭之后servlet并未销毁。后续演示。
总的来说servlet对象什么时候destroy的呢?
1、Tomcat服务器stop
2、web项目reload
3、Tomcat容器所在的服务器shutdown(这不废话吗?)
更正之处:对于destroy()方法笔者略有疑惑,“它到底是如何销毁Servlet的呢?”,基于这个问题
特意的去查看了源码,结果发现destroy()方法在Servlet框架中并未具体去实现。它是由Coder
自己去实现的。因此“destroy()方法用户销毁Servlet”这种说法本身就是离谱的!查阅源码:
阅读上述注释,很明白的是destroy的调用是表明Servlet结束其servcie阶段,destroy方法的调用
实际是在servlet销毁之前,由Tomcat来调用的,其作用是清理一些资源的占用情况,例如文件、
线程,而且确保任何持久的状态和servlet的当前状态在内存中是同步的。
不过destroy的调用情况上述的总结是正确的。
也就是说Servlet的销毁时destroy()一定会被掉用,servlet方法基本是由Tomcat回调的!
但是destroy()方法的调用只是回收一些资源,并不意味着Servlet已经销毁。至于何时销毁,这个
笔者也不太明了,希望有人可以指出,不过据源码是Servlet结束servcie服务时销毁,Tomcat关闭
时也会销毁。(皮之不存毛将安附焉?)
简单的测试下:
我们在doPost()方法里面简单的调用下destory方法,run项目,之后另起一个Session访问
输出情况:
这就说明了destroy()和Servlet的销毁不存在必然联系,只是在Servlet销毁之前,destroy方法,会
基由Tomcat回调,进行一些资源的清理,文件关闭。
Servlet生命周期演示
为了更进一步的了解Servlet生命周期(它确实十分重要),笔者新建一个简单的web项目予以说明
不当之处请指正,一起交流。
Eclipse配合Tomcat如何新建一个web项目,这个笔者就不必多说了吧,挺简单的,网上的总结
各式各样的也不少。不过需要注意的是高版本的Eclipse若果读者不注意的话产生的web项目是没有
web.xml文件的,以注解的形式代替了。
runtime选择自己配置好的Tomcat容器,web Module version选择2.5就可以了,不要选择3.0
这里笔者贴出项目中的一些歌主要的文件。
web.xml配置文件。
注意servlet映射的配置,以及初始化参数的配置。
自定义Servlet的代码:
接下来我们直接run该项目。看看后台输出结果,现在貌似可以直接在Eclispe控制台查看
输出信息了,十分方便。
init方法是在servlet实例化后由Tomcat容器进行调用的,生成了诸多信息,其中包含我们自己
定义的Servlet配置信息,在init方法中我们通过ServletConfig对象获取到了。
之后service方法执行了。这里新开启一个session会话,看看情况。图我就不贴了,控制台
多输出一句service被执行。证明了servlet在容器中实例单例的形式存在。源码层面上Servlet不是
单例的,只是由于容器对其的维护,使之产生了类似单例的效果。
接下来我们看destroy方法的调用情况,只是针对上述两种情况来说的,不可能笔者还去关机‘
演示。首先我们关闭Tomcat服务器
之后再Tomcat主页webapp管理上演示下reload,由于我们需要对Tomcat进行管理,我们将项目
打成war,单独运行Tomcat并发布war进行测试。
点击reload查看后台输出结果
对Servlet生命周期的问题就总结到这里了,笔者上述中有什么问题或者错误的地方希望读者给予
指正,大家多多交流。
对于Servlet的线程安全问题笔者会找个时间在学习下。
教程推荐:http://blog.csdn.net/lcore/article/details/8967528
相关推荐
java基础 一、仓库说明 Java基础类型,容器,并发,IO流,...Servlet基础,生命周期执行过程 Http请求详解,握手挥手流程简介 会话跟踪技术,Session和Cookie详解 过滤器、监听器、拦截器,应用详解 Servlet 集成 C3P0
Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大...
Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大...
Spring 是一个轻量级的依赖注入容器,它提供了一种灵活的方式来管理对象的生命周期和依赖关系。通过结合这三个框架,这个博客系统实现了一个完整的博客平台的功能。它包括了用户注册、登录、发布文章、评论、分类...
Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大...
Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大...
Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大...
生命周期 Kafka ... 设计模式 创建型 单例模式(Singleton) 简单工厂模式(Simple Factory) 工厂方法模式(Factory Method) 抽象工厂模式(Abstract Factory) 建造者模式(Builder) 原型模式(Prototype) 结构...
Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大...
9.4、Servlet生命周期 9.5、取得初始化配置信息 9.6、取得其他内置对象 9.6.1、取得HttpSession实例 9.6.2、取得ServletContext实例 9.7、Servlet跳转 9.7.1、客户端跳转 9.7.2、服务器端跳转 9.8、WEB开发...
│ Java面试题18.Servlet的生命周期.mp4 │ Java面试题19.forward和redirect的区别.mp4 │ Java面试题20.jsp和Servlet的相同点和不同点?.mp4 │ Java面试题21.内置对象和四大作用域和页面传值.mp4 │ Java面试题22....
9.4、Servlet生命周期 9.5、取得初始化配置信息 9.6、取得其他内置对象 9.6.1、取得HttpSession实例 9.6.2、取得ServletContext实例 9.7、Servlet跳转 9.7.1、客户端跳转 9.7.2、服务器端跳转 9.8、...
Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大...
Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。 Spring解决了开发者在J2EE开发中遇到的许多常见的问题,提供了功能强大...