一般Servlet只初始化一次(只有一个实例)。对于更多的客户端请求,Server创建新的请求和响应对象,仍然激活此Servlet的service()方法,将这两个对象作为参数传递给该方法。如此重复以上的循环,但无需再调用init()方法。

原因:

出于性能的考虑:特别的对于门户网站而言,每一个Servlet在每一秒内的并发访问量都可以是成千上万的。在一个面向模块化开发的现在,常常一个点击操作就被定义为一个Servlet的实现,而如果Servlet的每一次被访问,都创建一个新的实例的话,服务器的可用资源消耗量将是一个相当重要的问题。
退一步,一般Servlet的访问是很快的,每一个实例被快速的创建,又被快速的回收,GC的回收速度也跟不上,频繁的内存操作也将可能带来次生的问题。

所以,Servlet的“单一实例化”是一个很重要的策略。

此时为了更好理解servlet,这里附上servlet、httpservlet代码:

Servlet源代码:

package javax.servlet;
import java.io.IOException;
// Referenced classes of package javax.servlet:
// ServletException, ServletConfig, ServletRequest, ServletResponse
public interface Servlet
{
public abstract void init(ServletConfig servletconfig)
throws ServletException;
public abstract ServletConfig getServletConfig();
public abstract void service(ServletRequest servletrequest, ServletResponse servletresponse)
throws ServletException, IOException;
public abstract String getServletInfo();
public abstract void destroy();
}

HttpServlet源代码:

import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.ResourceBundle;
import javax.servlet.*;
// Referenced classes of package javax.servlet.http:
// NoBodyResponse, HttpServletRequest, HttpServletResponse
public abstract class HttpServlet extends GenericServlet
implements Serializable
{
public HttpServlet()
{
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if(protocol.endsWith("1.1"))
resp.sendError(405, msg);
else
resp.sendError(400, msg);
}
protected long getLastModified(HttpServletRequest req)
{
return -1L;
}
protected void doHead(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
NoBodyResponse response = new NoBodyResponse(resp);
doGet(req, response);
response.setContentLength();
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_post_not_supported");
if(protocol.endsWith("1.1"))
resp.sendError(405, msg);
else
resp.sendError(400, msg);
}
protected void doPut(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_put_not_supported");
if(protocol.endsWith("1.1"))
resp.sendError(405, msg);
else
resp.sendError(400, msg);
}
protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_delete_not_supported");
if(protocol.endsWith("1.1"))
resp.sendError(405, msg);
else
resp.sendError(400, msg);
}
private Method[] getAllDeclaredMethods(Class c)
{
if(c.equals(javax/servlet/http/HttpServlet))
return null;
Method parentMethods[] = getAllDeclaredMethods(c.getSuperclass());
Method thisMethods[] = c.getDeclaredMethods();
if(parentMethods != null && parentMethods.length > 0)
{
Method allMethods[] = new Method[parentMethods.length + thisMethods.length];
System.arraycopy(parentMethods, 0, allMethods, 0, parentMethods.length);
System.arraycopy(thisMethods, 0, allMethods, parentMethods.length, thisMethods.length);
thisMethods = allMethods;
}
return thisMethods;
}
protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
Method methods[] = getAllDeclaredMethods(getClass());
boolean ALLOW_GET = false;
boolean ALLOW_HEAD = false;
boolean ALLOW_POST = false;
boolean ALLOW_PUT = false;
boolean ALLOW_DELETE = false;
boolean ALLOW_TRACE = true;
boolean ALLOW_OPTIONS = true;
for(int i = 0; i < methods.length; i++)
{
Method m = methods[i];
if(m.getName().equals("doGet"))
{
ALLOW_GET = true;
ALLOW_HEAD = true;
}
if(m.getName().equals("doPost"))
ALLOW_POST = true;
if(m.getName().equals("doPut"))
ALLOW_PUT = true;
if(m.getName().equals("doDelete"))
ALLOW_DELETE = true;
}
String allow = null;
if(ALLOW_GET && allow == null)
allow = "GET";
if(ALLOW_HEAD)
if(allow == null)
allow = "HEAD";
else
allow = (new StringBuilder()).append(allow).append(", HEAD").toString();
if(ALLOW_POST)
if(allow == null)
allow = "POST";
else
allow = (new StringBuilder()).append(allow).append(", POST").toString();
if(ALLOW_PUT)
if(allow == null)
allow = "PUT";
else
allow = (new StringBuilder()).append(allow).append(", PUT").toString();
if(ALLOW_DELETE)
if(allow == null)
allow = "DELETE";
else
allow = (new StringBuilder()).append(allow).append(", DELETE").toString();
if(ALLOW_TRACE)
if(allow == null)
allow = "TRACE";
else
allow = (new StringBuilder()).append(allow).append(", TRACE").toString();
if(ALLOW_OPTIONS)
if(allow == null)
allow = "OPTIONS";
else
allow = (new StringBuilder()).append(allow).append(", OPTIONS").toString();
resp.setHeader("Allow", allow);
}
protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String CRLF = "\r\n";
String responseString = (new StringBuilder()).append("TRACE ").append(req.getRequestURI()).append(" ").append(req.getProtocol()).toString();
for(Enumeration reqHeaderEnum = req.getHeaderNames(); reqHeaderEnum.hasMoreElements();)
{
String headerName = (String)reqHeaderEnum.nextElement();
responseString = (new StringBuilder()).append(responseString).append(CRLF).append(headerName).append(": ").append(req.getHeader(headerName)).toString();
}
responseString = (new StringBuilder()).append(responseString).append(CRLF).toString();
int responseLength = responseString.length();
resp.setContentType("message/http");
resp.setContentLength(responseLength);
ServletOutputStream out = resp.getOutputStream();
out.print(responseString);
out.close();
}
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String method = req.getMethod();
if(method.equals("GET"))
{
long lastModified = getLastModified(req);
if(lastModified == -1L)
{
doGet(req, resp);
} else
{
long ifModifiedSince = req.getDateHeader("If-Modified-Since");
if(ifModifiedSince < (lastModified / 1000L) * 1000L)
{
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else
{
resp.setStatus(304);
}
}
} else
if(method.equals("HEAD"))
{
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else
if(method.equals("POST"))
doPost(req, resp);
else
if(method.equals("PUT"))
doPut(req, resp);
else
if(method.equals("DELETE"))
doDelete(req, resp);
else
if(method.equals("OPTIONS"))
doOptions(req, resp);
else
if(method.equals("TRACE"))
{
doTrace(req, resp);
} else
{
String errMsg = lStrings.getString("http.method_not_implemented");
Object errArgs[] = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
private void maybeSetLastModified(HttpServletResponse resp, long lastModified)
{
if(resp.containsHeader("Last-Modified"))
return;
if(lastModified >= 0L)
resp.setDateHeader("Last-Modified", lastModified);
}
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
{
HttpServletRequest request;
HttpServletResponse response;
try
{
request = (HttpServletRequest)req;
response = (HttpServletResponse)res;
}
catch(ClassCastException e)
{
throw new ServletException("non-HTTP request or response");
}
service(request, response);
}
private static final String METHOD_DELETE = "DELETE";
private static final String METHOD_HEAD = "HEAD";
private static final String METHOD_GET = "GET";
private static final String METHOD_OPTIONS = "OPTIONS";
private static final String METHOD_POST = "POST";
private static final String METHOD_PUT = "PUT";
private static final String METHOD_TRACE = "TRACE";
private static final String HEADER_IFMODSINCE = "If-Modified-Since";
private static final String HEADER_LASTMOD = "Last-Modified";
private static final String LSTRING_FILE = "javax.servlet.http.LocalStrings";
private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.http.LocalStrings");
}
参考:《.init()方法成功完成后,Servlet可以接受请求.默认有多少个Servlet实例被创建》、《Java Servlet(二):servlet配置及生命周期相关(jdk7+tomcat7+eclipse)

Java Servlet(十一):一个servlet被10个浏览器客户端访问时会创建几个servlet实例?的更多相关文章

  1. java nio 写一个完整的http服务器 支持文件上传 chunk传输 gzip 压缩 使用过程 和servlet差不多

    java nio 写一个完整的http服务器  支持文件上传   chunk传输    gzip 压缩      也仿照着 netty处理了NIO的空轮询BUG        本项目并不复杂 代码不多 ...

  2. java web第一个Servlet程序

    Servlet 简介 . Java Servlet是和平台无关的服务器端组件,它运行在Serlet容器中.Servlet容器负责Servlet和客户的通信以及调用Servlet的方法,Servlet和 ...

  3. 每一个Servlet只有一个实例,多个线程

    每一个Servlet只有一个实例,多个线程: Servlet: package com.stono.servlet.synchronize; import javax.servlet.http.Htt ...

  4. 基于servlet实现一个web框架

    servlet作为一个web规范.其本身就算做一个web开发框架,可是其web action (响应某个URI的实现)的实现都是基于类的,不是非常方便,而且3.0之前的版本号还必须通过web.xml配 ...

  5. servlet的一个web容器中有且只有一个servlet实例或有多个实例的理解1

    servlet的一个web容器中有且只有一个servlet实例或有多个实例的理解 (2013-06-19 19:30:40) 转载▼     servlet的非线程安全,action的线程安全 对提交 ...

  6. 用Intellij Idea创建简单的Servlet

    Servlet作为Java服务端程序,使用起来还是挺方便的,下面是具体配置过程,我用的是Intellij Idea. 1. 做好必要准备,Intellij Idea(或者Eclipse for J2E ...

  7. developerWorks 图书频道: 深入分析 Java Web 技术内幕,第 10 章

    developerWorks 图书频道: 深入分析 Java Web 技术内幕,第 10 章 深入理解 Session 与 Cookie Session 与 Cookie 不管是对 Java Web ...

  8. 在Eclipse中配置Tomcat 创建和运行Servlet/JSP

    在Eclipse中配置Tomcat 创建和运行Servlet/JSP 步骤一:在Eclipse中配置Tomcat(注意下载Eclipse IDE for Java EE Developers) (1) ...

  9. 【转】Eclipse中创建并运行Servlet项目

    最近看了写http协议的学习资料,因此想要实现下andriod平台和服务器通信,那就servlet吧,哎哟,还不错哦!顺便说下,我这个servlet服务是想获得用户名和密码进行校验,然后反给客户端状态 ...

随机推荐

  1. Office远程代码执行漏洞(CVE-2017-11882)复现

    昨晚看到的有复现的文章,一直到今天才去自己复现了一遍,还是例行记录一下. POC: https://github.com/Ridter/CVE-2017-11882/ 一.简单的生成弹计算器的doc文 ...

  2. 1-7 hibernate关联关系映射

    1.关联关系分为单向关联(一对一,一对多,多对一,多对多),多向关联(一对一,一对多,多对多). 2.单向一对一主键关联实例 需要为one-to-one元素指定constrained属性值为true. ...

  3. Linux(CentOS 7)环境下安装MySQL

    在CentOS中默认安装有MariaDB,但是我们需要的是MySQL,安装MySQL可以覆盖MariaDB MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可 ...

  4. [Tarjan 学习笔记](无向图)

    今天考试因为不会敲 Dcc 的板子导致没有AK(还不是你太菜了),所以特地写一篇博客记录 Tarjan 的各种算法 无向图的割点与桥 (各种定义跳过) 割边判定法则 无向边 (x,y) 是桥,当且仅当 ...

  5. spring 文件模板下载多种实现方式

    针对于文件的下载,我们有很多种实现方式.业务场景是这样子的,要实现Excel文件的导入和导出功能,问题对于java的POI操作没有问题,所以实现文件的下载就相对简单,只需要从数据库取出相关的数据,针对 ...

  6. Vmware虚拟机不能使用键盘的解决方法

    有个笔记本thinkpad T440要重装系统,但又怕前面的资料丢失,因此打算直接将整个物理机迁移到VCenter 6.5上去,比GHOST什么的方便多了,利用Vmware Convert工具直接在线 ...

  7. 将 Shiro 作为应用的权限基础 四:shiro的配置说明

    Apache Shiro的配置主要分为四部分: SecurityManager的配置 URL过滤器的配置 静态用户配置 静态角色配置 其中,由于用户.角色一般由后台进行操作的动态数据,比如通过@Req ...

  8. 解决设置clickablespan后长按冲突的问题

    解决设置ClickableSpan后长按冲突的问题 问题描述 3月份修改别人代码的时候想要屏蔽TextView的长按事件,发现TextView有重写OnTouchEvent方法,然后在其中加了长按事件 ...

  9. 移动端H5地图矢量SHP网格切分打包方案

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 与离线瓦片方案一样,同样是为了解决移动端网速和流量问题,但是却 ...

  10. mysql基础篇 - 其他基本操作

    基础篇 - 其他基本操作         其他基本操作 一.实验简介 本节实验中我们将学习并实践数据库的其他基本操作:索引.视图,导入和导出,备份和恢复等. 这些概念对于数据库管理员而言都非常重要,请 ...