
Servlet是一个java编写的程序,此程序是在服务器端运行的,
是按照Servlet规范编写的一个
java类。Servlet是处理客户端的请求,并将处理结果以响应的
方式返回给客户端。Servlet框架
是怎样的呢?它的生命周期又是什么情况呢?这是本文需要探
求的
Tomcat 执行 servlet 架构图 从上面可以得出结论: http://localhost:8080/ks/login ---- 1.程序如果一旦打成 war 包,扔 tomcat 中,其实就已经和开 发环境没有任何联系和瓜葛 2.应用程序与应用程序直接,是通过上下文 Context 来隔离 3.其实我们在程序中编写的大量的 Servlet 其实都在给 Tomcat 编写子类。给 HttpServlet 编写子类 4. 如果 tomcat 一旦运行起来,那么就把应用程序所有对应 的子类 Servlet 全部加载内存中(没有实例化),然后用 上线文隔离,准备接受请求。 5. 如果用户一旦发起 http 请求,如果协议和端口都是一致 的,并且上下文 Context 匹配的。然后调用执行引擎 Engine 类,这个引擎类就把要执行的请求对象,响应对 象初始化准备好。(这个都有 HttpServletRequest, HttpServletResponse ) 6. 然后通过你路由地址,根据你 path=/login----> 映射的 class---com.kuangstudy.LoginServlet --- 用反射实例化 LoginServlet 对象, 但是它只会实例化一次* Called by the servlet container to indicate to a servlet that the * servlet is being placed into service. * * 响应客户请求阶段 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 中的主 要的逻辑处理阶段The servlet container calls the init * method exactly once after instantiating the servlet. * The init method must complete successfully * before the servlet can receive any requests. * *
The servlet container cannot place the servlet into service * if the init method *
*
- Throws a ServletException *
- Does not return within a time period defined by the Web server
protected void service(HttpServletRequest
req, HttpServletResponse resp)
2 throws ServletException, IOException
3 {
4 String method = req.getMethod();
5
6 if (method.equals(METHOD_GET)) {
7 long lastModified =
getLastModified(req);
8 if (lastModified == -1) {
9 // servlet doesn't support if-
modified-since, no reason
10 // to go through further expensive
logic
11 doGet(req, resp);
12 } else {
13 long ifModifiedSince =
req.getDateHeader(HEADER_IFMODSINCE);
14 if (ifModifiedSince < (lastModified
/ 1000 * 1000)) {
15 // If the servlet mod time is
later, call doGet()
16 // Round down to the
nearest second for a proper compare
17 // A ifModifiedSince of
-1 will always be less
18 maybeSetLastModified(resp,
lastModified);
19 doGet(req, resp);
20 } else {21
resp.setStatus(HttpServletResponse.SC_NOT_MO
DIFIED);
22 }
23 }
24
25 } else if (method.equals(METHOD_HEAD)) {
26 long lastModified =
getLastModified(req);
27 maybeSetLastModified(resp,
lastModified);
28 doHead(req, resp);
29
30 } else if (method.equals(METHOD_POST)) {
31 doPost(req, resp);
32
33 } else if (method.equals(METHOD_PUT)) {
34 doPut(req, resp);
35
36 } else if (method.equals(METHOD_DELETE))
{
37 doDelete(req, resp);
38
39 } else if
(method.equals(METHOD_OPTIONS)) {
40 doOptions(req,resp);
41
42 } else if (method.equals(METHOD_TRACE))
{
43 doTrace(req,resp);
44
45 } else {
46 //
47 // Note that this means NO servlet
supports whatever
48 // method was requested, anywhere on
this server.
49 //50
51 String errMsg =
lStrings.getString("http.method_not_implemen
ted");
52 Object[] errArgs = new Object[1];
53 errArgs[0] = method;
54 errMsg =
MessageFormat.format(errMsg, errArgs);
55
56
resp.sendError(HttpServletResponse.SC_NOT_IM
PLEMENTED, errMsg);
57 }
58 }
终止阶段:
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”
这种说法
本身就是离谱的!
destory
方法
此方法,并不是说当前
LoginServlet
执行请求结束之后执
行的方法。
tomcat
容器如果内部执行
reload
或者关闭的服务器,会来
触发执行
其实
tomcat
内部也并没有具体实现,其实这个方
法,没有什么意义欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)