package com.xxxx.java;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class Servletlife implements Servlet {
/*建立一个无参的构造函数*/
public Servletlife(){
System.out.println("Servletlitf's Construct methord execute");
}
@Override
public void destroy() {
System.out.println("Servletlitf's destroy methord execute");
}
@Override
public ServletConfig getServletConfig() {
//System.out.println("Servletlitf's getServletConfig methor execute");
return null;
}
@Override
public String getServletInfo() {
//System.out.println("Servletlitf's getServletInfo methor execute");
return null;
}
@Override
public void init(ServletConfig arg0) throws ServletException {
System.out.println("Servletlitf's init methor execute");
}
@Override
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
System.out.println("Servletlitf's service methor execute");
}
}
关于Servlet对象的生命周期
1、什么是生命周期
生命周期表示一个java对象从最初被创建到最终被销毁,经历的所有过程。
2、Servlet对象的生命周期是谁来管理的?程序员可以干涉吗?
Servlet对象的生命周期,javaweb程序员是无权干涉的,包括Servlet对象的相关方法的调用,javaweb程序员也是无权干涉的。
Servlet对象从最初的创建,方法的调用,以及对象的销毁,整个过程,是由web容器管理的。
Web Container管理Servlet对象的生命周期。
3、"默认情况下",Servlet对象在WEB服务器启动阶段不会被实例化。
4、描述Servlet对象的生命周期
1) 用户在浏览器地址栏上输入URL:http://localhost:8080/prj-servlet/testLifeCycle
2) web容器截取请求路径: /prj-serlet-03/testLifeCycle
3) web容器在容器上下文中找请求路径 /prj-servlet-03/testLifeCycle对应的Servlet对象
4) 若没有找对应的Servlet对象
4.1)通过web.xml文件中相关的配置信息,得到请求路径/testLifeCycle对应的Servlet完整的类名
4.2)通过反射机制,调用Servlet类的无参构造方法完成Servlet对象的实例化
4.3)web容器调用Servlet对象的init方法完成初始化操作
4.4) web容器调用Servlet对象的service方法提供服务
5)若找到对应的Servlet对象
5.1)web容器直接调用Servlet对象的Service方法提供服务
6) web容器关闭的时候/webapp重新部署的时候该Servlet对象长时间没有用户再次访问的时候,web容器会将该Servlet对象销毁,在销毁该对象之前,web容器会调用Servlet对象的destroy方法,完成销毁之前的准备。
5、总结:
5.1 Servlet类的构造方法只执行一次
5.2 Servlet对象的init方法只执行一次
5.3 Servlet对象的service方法,只要用户请求一次,则执行一次
5.4 Servlet对象的destroy方法只执行一次
6、注意:
init方法执行的时候,Servlet对象已经被创建好了。
destory方法执行的时候,Servlet对象还没有被销毁,即将被销毁
7、Servlet对象是单例,但是不符合单例模式,只能称为伪单例。真单例的构造方法是私有化的,Tomcat服务器是支持多线程的。所以Sservlet对象在单实例多线程的环境下运行的。那么Servlet对象中若有实例变量,并且实例变量涉及到修改操作,那么这个Servlet对象一定会存在线程安全问题,不建议在Servlet对象中使用实例变量,尽量使用局部变量
8、若希望在web服务器启动阶段实例化Servlet对象,需要在web.xml文件中进行相关的配置,例如:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>testlife0</servlet-name>
<servlet-class>com.xxx.java.Servletlife</servlet-class>
<!-- 在服务器启动阶段创建Servlet对象 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>testlife0</servlet-name>
<url-pattern>/Servletlife</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>testlife1</servlet-name>
<servlet-class>com.xxx.java.WelcomeServlet</servlet-class>
<!-- 在服务器启动阶段创建Servlet对象 -->
<!--这里的1和0是有差别的,越靠前越先执行-->
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>testlife1</servlet-name>
<url-pattern>/WelcomeServlet</url-pattern>
</servlet-mapping>
</web-app>
9、Servlet对象实例化之后,这个Servlet对象被存储到哪里了?
大多数的WEB容器都是该Servlet对象以及对应的url-pattern存储到Map集合中了:
在WEB容器中有这样一个Map集合
Map<String, Servlet> 集合
key value
----------------------
/login LoginServlet对象引用
/delete DeleteServlet对象引用
/save SaveServlet对象引用
........
10、服务器在启动的时候就会解析各个webapp的web.xml文件,做了什么?
将web.xml文件中的url-pattern和对应的Servlet完整类名存储到Map集合中:
在WEB容器中有这样一个Map集合
Map<String, String> 集合
key value
--------------------------
/login com.xxx.javaweb.servlet.LoginServlet
/delete com.xxx.javaweb.servlet.DeleteServlet
......
11、Servlet接口中的这些方法中编写什么代码?什么时候使用这些方法?
1)无参数构造方法【以后就不需要再考虑构造函数了,尽量别动构造函数】
2)init方法
以上两个方法执行时间几乎是相同的,执行次数都是一次,构造方法执行的时候对象正在创建,init方法执行的时候对象已经创建:
若系统要求在对象创建时刻执行一段特殊的程序,这段程序尽量些到init方法中。为什么不建议写在构造函数中呢?存在风险!
当啊程序员编写构造方法的时候,可能会导致i无参数构造方法的不存在。
一个类不编写任何构造函数,默认有一个无参数的构造方法,但是一旦编写一个有参数的构造方法之后,系统则不再提供无参数构造函数。
Servlet中的init方法是SUN公司为javaweb程序员专门提供的一个初始化时刻,若希望在初始化时刻执行一段特殊的程序,这个程序可以编写到init方法,将来回自动被调用。
3)service方法
这个方法是必然重写的,因为这个方法需要完成业务逻辑的处理,请求的处理,以及完成响应。
而且这个方法中的代码是最有价值的。
也是最难写的,因为最难编写的就是业务代码了。
4)destroy方法
这个方法也是SUN公司为javaweb程序员提供的一个特殊时刻,这个特殊的时刻被称为对象销毁时刻,
若希望在销毁时刻执行一段特殊的代码,需要将这段代码编写到destroy方法,自动被容器调用。
回顾:
类加载时刻执行程序,代码写到哪里?
编写到静态代码块中。
结论:
sun公司为我们程序员提供了很多个不同的时刻。若在这个特殊的时刻执行特殊程序,这些程序是有位置编写的。