servlet执⾏流程和⽣命周期
⼀、servlet执⾏流程:
⼆、⽣命周期:
Servlet的⽣命周期可以分为四个阶段,即装载类及创建实例阶段、初始化阶段、服务阶段和实例销毁阶段。
1、初始化阶段调⽤init()⽅法
2、响应客户请求阶段。调⽤service()⽅法,由service()⽅法根据提交的⽅式选择执⾏doGet()或者doPost()⽅法
3、终⽌阶段 调⽤destroy()⽅法
1、创建servlet实例:
在默认情况下Servlet实例是在第⼀个请求到来的时候创建,以后复⽤。如果有的Servlet需要复杂的操作需要载初始化时完成,⽐如打开⽂件、初始化⽹络连接等,可以通知服务器在启动的时候创建该Servlet的实例。具体配置如下:
<servlet>
<servlet-name>TimeServlet</servlet-name>
<servlet-class>com.allanlxf.servlet.basic.TimeServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
创建servlet对象的相关类结构:
2、初始化
⼀旦Servlet实例被创建,Web服务器会⾃动调⽤init(ServletConfig config)⽅法来初始化该Servlet。其中⽅法参数config中包含了Servlet 的配置信息,⽐如初始化参数,该对象由服务器创建。
I.如何配置Servlet的初始化参数?
在l中该Servlet的定义标记中,⽐如:
<servlet>
<servlet-name>TimeServlet</servlet-name>
<servlet-class>com.allanlxf.servlet.basic.TimeServlet</servlet-class>
<init-param>
<param-name>user</param-name>
<param-value>username</param-value>
</init-param>
<init-param>
<param-name>blog</param-name>
<param-value>。。。</param-value>
</init-param>
</servlet>
配置了两个初始化参数user和blog它们的值分别为username和。。。,这样以后要修改⽤户名和博客的地址不需要修改Servlet代码,只需修改配置⽂件即可。
II.如何读取Servlet的初始化参数?
ServletConfig中定义了如下的⽅法⽤来读取初始化参数的信息:
public String getInitParameter(String name)
参数:初始化参数的名称。
返回:初始化参数的值,如果没有配置,返回null。
III.init(ServletConfig)⽅法执⾏次数
在Servlet的⽣命周期中,该⽅法执⾏⼀次。
IV.init(ServletConfig)⽅法与线程
该⽅法执⾏在单线程的环境下,因此开发者不⽤考虑线程安全的问题。
V.init(ServletConfig)⽅法与异常
该⽅法在执⾏过程中可以抛出ServletException来通知Web服务器Servlet实例初始化失败。⼀旦ServletException抛出,Web服务器不会将客户端请求交给该Servlet实例来处理,⽽是报告初始化失败异常信息给客户端,该Servlet实例将被从内存中销毁。如果在来新的请
求,Web服务器会创建新的Servlet实例,并执⾏新实例的初始化操作
3、服务
⼀旦Servlet实例成功创建及初始化,该Servlet实例就可以被服务器⽤来服务于客户端的请求并⽣成响应。在服务阶段Web服务器会调⽤该实例的service(ServletRequest request, ServletResponse response)⽅法,request对象和response对象有服务器创建并传给Servlet实例。request对象封装了客户端发往服务器端的信息,response对象封装了服务器发往客户端的信息。
I. service()⽅法的职责
service()⽅法为Servlet的核⼼⽅法,客户端的业务逻辑应该在该⽅法内执⾏,典型的服务⽅法的开发流程为:
解析客户端请求-〉执⾏业务逻辑-〉输出响应页⾯到客户端
II.service()⽅法与线程
为了提⾼效率,Servlet规范要求⼀个Servlet实例必须能够同时服务于多个客户端请求,即service()⽅法运⾏在多线程的环境下,Servlet 开发者必须保证该⽅法的线程安全性。
III.service()⽅法与异常
service()⽅法在执⾏的过程中可以抛出ServletException和IOException。其中ServletException可以在处理客户端请求的过程中抛出,⽐如请求的资源不可⽤、数据库不可⽤等。⼀旦该异常抛出,容器必须回收请求对象,并报告客户端该异常信息。IOException表⽰输⼊输出的错误,编程者不必关⼼该异常,直接由容器报告给客户端即可。
编程注意事项说明:
1) 当Server Thread线程执⾏Servlet实例的init()⽅法时,所有的Client Service Thread线程都不能执⾏该实例的service()⽅法,更没有线程能够执⾏该实例的destroy()⽅法,因此Servlet的init()⽅法是⼯作在单线程的环境下,开发者不必考虑任何线程安全的问题。
2) 当服务器接收到来⾃客户端的多个请求时,服务器会在单独的Client Service Thread线程中执⾏Servlet实例的service()⽅法服务于每个客户端。此时会有多个线程同时执⾏同⼀个Servlet实例的service()⽅法,因此必须考虑线程安全的问题。
3) 请⼤家注意,虽然service()⽅法运⾏在多线程的环境下,并不⼀定要同步该⽅法。⽽是要看这个⽅法在执⾏过程中访问的资源类型及对资源的访问⽅式。分析如下:
i. 如果service()⽅法没有访问Servlet的成员变量也没有访问全局的资源⽐如静态变量、⽂件、数据库连接等,⽽是只使⽤了当前线程⾃⼰的资源,⽐如⾮指向全局资源的临时变量、request和response对象等。该⽅法本⾝就是线程安全的,不必进⾏任何的同步控制。
ii. 如果service()⽅法访问了Servlet的成员变量,但是对该变量的操作是只读操作,该⽅法本⾝就是线程安全的,不必进⾏任何的同步控制。
iii. 如果service()⽅法访问了Servlet的成员变量,并且对该变量的操作既有读⼜有写,通常需要加上同步控制语句。
iv. 如果service()⽅法访问了全局的静态变量,如果同⼀时刻系统中也可能有其它线程访问该静态变量,如果既有读也有写的操作,通常需要加上同步控制语句。
v. 如果service()⽅法访问了全局的资源,⽐如⽂件、数据库连接等,通常需要加上同步控制语句。
4、销毁
当Web服务器认为Servlet实例没有存在的必要了,⽐如应⽤重新装载,或服务器关闭,以及Servlet很长时间都没有被访问过。服务器可以从内存中销毁(也叫卸载)该实例。Web服务器必须保证在卸载Servlet实例之前调⽤该实例的destroy()⽅法,以便回收Servlet申请的资源或进⾏其它的重要的处理。
Web服务器必须保证调⽤destroy()⽅法之前,让所有正在运⾏在该实例的service()⽅法中的线程退出或者等待这些线程⼀段时间。⼀旦destroy()⽅法已经执⾏,Web服务器将拒绝所有的新到来的对该Servlet实例的请求,destroy()⽅法退出,该Servlet实例即可以被垃圾回收。
四、servlet解析客户端http请求流程图:
1. web客户向Servlet容器发出HTTP请求;
2. Servlet容器解析web的HTTP请求.
3. Servlet容器创建⼀个HttpRequest对象,在这个对象中封装了http请求信息;
4. Servlet容器创建⼀个HttpResponse对象;
5. Servlet容器(如果访问的该servlet不是在服务器启动时创建的,则先创建servlet实例并调⽤init()⽅法初始化对象)调⽤HttpServlet的service()⽅法,把HttpRequest和HttpResponse对象为service⽅法的参数传给HttpServlet对象;
6. HttpServlet调⽤HttpRequest的有关⽅法,获取HTTP请求信息;
7. HttpServlet调⽤HttpResponse的有关⽅法,⽣成响应数据;
8. Servlet容器把HttpServlet的响应结果传给web客户.
三、Tomcat装载servlet三种⽅法:
1、Serlvet容器启动时⾃动装载某些Servlet,实现它只需要在l⽂件中
<servlet> </servlet>之间添加<load-on-startup>1</load-on-startup>,数字越⼩,优先级越⼤。
servlet和tomcat的关系2、在Servlet容器启动时,客户⾸次向Servlet发送请求
3、Servlet类⽂件被更新后,重新装载Servlet
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论