Servlet 生命周期介绍

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/nvd11/article/details/43610663

在面试的时候.

有时会被问到这个问题: 请描述一下Servlet的生命周期.

其实面试官就是想问你1个Servlet何时被创建, 何时被调用等....


本文就是详细解答这个问题的.



总体流程图



上面的流程图从输入网址 到浏览器地址栏开始, 到Web 服务器软件关闭结束.

其中白底色的图形代表的是浏览器在工作.

灰底色的指的是Web服务器软件(例如Tomcat, IIS等)

黄底色的代表的是Servlet对象本身在工作.


下面对这个流程图的每一步都进行解析.


一, 浏览器地址输入地址

例如上面的地址栏输入

http://localhost:8080/TestServlet2/ABC


其中:

http 指的是网页浏览协议,  大部分常用的都是http协议,  需要严格安全管理的(例如需要传送密码的)的网页往往会使用https 协议.

localhost 指的服务器名称. 也就是浏览器要从网络哪一台主机去获得需要浏览的内容.

8080 指的是服务器的Web 服务器程序用的是哪一个端口.   大部分网站都会让web 服务器软件使用80端口, 那么浏览器地址栏就不用输入端口(默认就是80), tomcat默认使用的端口是8080.

TestServlet2 指的是网络应用程序的名字, 这个应用程序是部署在web主机的web服务器软件内的.  记住, 这个网络应用程序只是针对J2EE来讲的.  并不一定适用于其他技术编写的网站(如asp.net. psp等)

ABC 只于这个地址名称就是定义在servlet配置中的(一般在WEB-INF/web.xml中, 应用MVC的框架则可能配置在Control 类里)URL后序.  每1个后序关键字对应1个Servlet对象. Web服务器软件会将Http协议Get请求发送到这个servlet对象, 交由它处理.



二, 浏览器分析地址获得Web主机的ip

例如上面那条URL,  主机别名是localhost.

那么浏览器如何根据localhost 这个关键字获得对应的ip.


第一步就是去浏览器所在机器的host文件去找.

例如linux机器的host 文件/etc/hosts 是这样的: (windows也有host文件, 具体位置忘了)

gateman@TPEOS ~ $ cat /etc/hosts
127.0.0.1	localhost
127.0.1.1	TPEOS
192.168.1.104 S960 
#172.18.6.140 TPRHEL
192.168.1.105 TPRHEL
#192.168.20.57 TPRHEL

可以到localhost 正是对应 127.0.0.1 就是本机地址了.


也就是讲, 浏览器会将localhost解析成127.0.0.1的地址.


但是如果在host文件里找不到, 例如输入www.163.com?

这是浏览器就需要到dns服务器去找, 总之, 必须解析出主机地址.


三,尝试与web主机的web服务器软件建立连接.

之前讲过TCP协议了, 只需要知道主机地址和端口. 就可以利用socket发起1个连接请求.

Web服务器端, 一旦接受请求, 则会建立一条TCP传输通道.  


这个通道里面包含两条Stream, 方向相反.



四, 浏览器发送http请求(Get/post)到web服务器软件.

一旦浏览器与Web主机的服务器软件(例如Tomcat, Jboss,IIS..)建立了一条连接通道.

浏览器就会按照Http协议发送get请求到web服务器软件.


如上图, 在浏览器按下F12可以看到开发者信息.


这个简单的例子中,  浏览器只发送了1个Get请求到服务器软件.

在右下角可以见到该get请求的内容:

Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:35.0) Gecko/20100101 Firefox/35.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive

包括host信息,  浏览器与操作系统信息等等..


实际上, 在上图我们也看到服务器的反馈(respones) . 这个后面再讲.



五, Web服务器软件解析出对应Web应用程序.

好了, 到这一步, 主要工作就轮到Web服务器软件了.

首先, Server App会继续解析URL(包括在Get request)中.

对于Tomcat来讲, 这一步会解析出对应的web 应用程序 TestServlet2


注: 1个web服务器软件通常会同时管理多个网络应用程序.



六, Web服务器软件解析出对应的URL后序.

好了, 到了这步,   整个URL

http://localhost:8080/TestServlet2/ABC

就剩下/ABC 这一部分了.


这部分通常是Servlet来(本文就是基于Servlet技术来讲的) 管理,  对应关系通常编写在../WEB-INF/web.xml里( MVC框架也可能在Controller类里)


这个例子中. web.xml 的 Servlet配置部分是这样写的:

<!-- servlet-name is the nick name of servlet object
  		The source name is user defined, 
  		it's suggested that using the name of servlet class 
  		
  		servlet-class is the full name(include packege path) of the servlet object
  -->
  <servlet>
 	<servlet-name>MyFirstServlet</servlet-name> 
 	<servlet-class>com.pkg1.MyFirstServlet</servlet-class> 
  </servlet>
  
  
  <!-- the mapping of servlet of jsp action
  	the servlet-name must be same with the above "servlet-name"
  	url-pattern is the source name of which will access servlet object
  	it must be started with "/"
   -->
   
  <servlet-mapping>
 	<servlet-name>MyFirstServlet</servlet-name> 
 	<url-pattern>/ABC</url-pattern>
  </servlet-mapping>


先看servlet-mapping部分

/ABC 这个url match的是 MyFirstServlet 这个 Servlet 昵称(Nick Name).


然后看servlet部分.

MyFirstServlet 对应的就是

com.pkg1.MyFirstServlet

而这个就是真正的要工作的Servlet类.


七, Web服务器软件检查Servlet对象是否存在.

在web世界中, 我们可以把每1个Servlet类都看成Singleton 类.

也就是讲, 对于每1个Servlet类, 都只会有最多1个对象在工作, 不会同时存在两个相同Servlet类的对象.


例如第6步, 根据/ABC  得出com.pkg1.MyFirstServlet类后.  Web服务器软件就会去检查是否有1个对应的servlet对象已经被创建.


如果有则跳过第八步.




八, Web服务器软件构造出Servlet对象.

注意, 这一步有1个前提, 就是当前该Servlet没有任何1个对象被创建.(或者之前的被销毁)


而我们常写的Servlet类都没有写构造函数的.
一般是重写 Init(), doGet(). doPost()..


实际上, 这个Servlet不是被new出来的, 而是web服务器软件利用反射技术构建.( 根据类名创建该类的对象)


在这过程中, 这个Servlet里的init()函数会被执行一次.

而无论这个Servlet对象再被调用多少次, init()方法都不会再杯执行, 直至销毁后重新创建.



九, Web服务器软件把接收到的http 请求打包成1个ServletRequest对象, 在构造1个ServletResponse对象发给Servlet对象.

再得到1个Servlet对象后.

Web服务器软件, 就会把从浏览器接收到的Http请求交给Servlet来处理.


其中ServletRequest对象里包含里传入的参数, 而ServletResponese对象用于获取Servlet对象的处理结果



十, Servlet对象工作

这里的代码通常就是程序猿写的业务代码了


无非分两个步骤

1, 处理传入的ServletRequest对象里的信息

2. 把结果放在ServletRespones的对象里面(通常是利用里面的OutputStream)


这个例子的代码:

        System.out.println("service() has been called!"); 
        res.getWriter().println("<font color=\"blue\" style=\"font-size:40px;\">Just a testing</font>");
        res.getWriter().flush();



可见它往ServletResponse对象的outputStream写入了一段很简单的html语句..


这个一步就是Servlet生命周期最核心的一步, 也是最常用的一步, 1个Servlet可能会被调用很多次, 这个就是Servlet对象的存在意义.



十一, WebServer 软件对返回信息进行处理

Web服务器软件会从ServletResponse这个对象中得出Servlet工作处理完的反馈信息.

但是这些信息通常不能被浏览器直接解析(或者很耗时间)


所以WebServer软件通常会将这些信息翻译成浏览器能直接阅读的格式.


十二, WebServer 把返回信息发送会浏览器


看上图右下角, 我们可以观察得reponse里面的内容就是 servlet往outputStream写的内容.

所以浏览器就中直接显示3个蓝色的单词了.



十三, 如果对应的网络程序被reload或者webServer本身被关闭, 则servlet对象会被销毁

这个就是Servlet生命周期的最后一步了, 不难理解.

这时, servlet对象会执行自己的destory()方法.












































猜你喜欢

转载自blog.csdn.net/nvd11/article/details/43610663
今日推荐