首先创建一个Servlet类
public class ZZServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
System.out.println("service"/*+name*/);
super.service(arg0, arg1);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet");
response.getWriter().append("Served at: ").append(request.getContextPath());
}
}
创建对象
将来这个Servlet类必然是要创建对象的,因为此处没有写构造方法,所以创建对象必然调用的是无参构造方法,此时我们在此处定义一个无参构造方法,通过添加打印语句,便于在控制台观察何时创建对象
public ZZServlet() {
System.out.println("ZZServlet");
}
然后我们发布,在页面上点击链接
再后退,在点击链接
对比得出结论,默认情况下,第一次使用Servlet,则创建对象,以后再次使用不再创建,
如果在web.xml相应的servlet相应的标签内添加/</load-on-startup/>0</load-on-startup/>,则对象随tomcat服务器启动而创建,如图所示,启动过程中创建对象
初始化
引入无参的init方法
@Override
public void init() throws ServletException {
System.out.println("init");
}
再次发布
说明init()方法在对象创建完之后就会执行,因为init方法是个非静态方法,所以需要创建对象才能执行
所以init()方法在servlet对象创建完之后立即执行,因为servlet对象只创建一次,所以该方法只执行一次,页面中多次发送请求,控制台输出如下
注销
引入destroy()方法
并注掉或者说关闭自动/</load-on-startup/>0</load-on-startup/>
@Override
public void destroy() {
System.out.println("destroy");
super.destroy();
}
情景一
正常启动,正常关闭,不点击链接即不创建对象
结果是,方法都不执行;
情景二
正常启动,点击链接,创建对象,正常关闭
结果是,会执行destroy方法
情景三
正常启动,点击链接创建对象,暴力关闭
结果,不执行destroy方法
情景四,
正常启动,点击链接创建对象,remove项目
报错,但执行克destroy方法
总结
销毁Servlet 由Servlet容器完成。默认情况下,用户第一次发送Servlet请求,该Servlet加载、实例化、初始化、处理用户请求,当请求处理完毕后,该Servlet通常情况下驻留在内存中,等待处理下一个针对该Servlet的请求。当下一个针对该Servlet的请求到达时,直接从内存中获取该Servlet实例并对该请求进行处理。如果Tomcat这个Web应用服务器关闭(服务器上所有的Web应用都关闭),或者该Servlet所在的Web应用关闭,该Servlet实例会被销毁。
Web应用被关闭时,Servlet容器会先调用Servlet实例的destroy方法,然后再销毁Servlet实例,同时也会销毁与Servlet相关联的ServletConfig对象。程序员通常在destroy()方法的实现中释放该Servlet所占用的资源,如关闭数据库连接,关闭文件输入/输出流等。
通过Servlet声明周期可以知道所创建的Servlet对象属于单例。
需要补充的是
处理请求.
service方法,根据requset执行get或post方法
Servlet初始化之后,就处于就绪状态等待接收用户请求。当Servlet容器接收到客户端针对该Servlet的请求后,首先会针对这个请求创建ServletRequest和ServletResponse对象,之后调用Servlet的service()方法并把这两个参数传递给service()方法处理客户端请求。Servlet实例通过ServletRequest对象获得客户端的请求,通过调用ServletResponse对象的方法进行响应。请求处理完毕,ServletRequest和ServletResponse对象被销毁。
不管客户端发送请求的方式是Get还是POST,这个请求都由service方法来处理。在service方法的处理过程中,会根据客户端发送请求的方式不同,调用doGet和doPost方法分别进行处理,通过HttpServlet类中的service方法可以了解这一调用过程
protected void service(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
if (ifModifiedSince < lastModified) {
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
} else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp);