1,概述(Servlet生命周期):首先加载Servlet的实现类,当客户端通过网络访问服务器时,实例化Servlet对象;然后调用Servlet类中的init方法设置Servlet对象的config成员,并执行service方法;当不再有客户端访问服务器,web-app将会调用Servlet类中的destroy方法销毁Servlet对象,到此Servlet对象的生命周期结束。
2,步骤一:Servlet实现类的加载
(1)所有的web-server加载Servlet实现类的时候,都将搜索web-app根目录下WEB-INF目录的子目录lib和classes,在lib目录中搜索*.jar文件(lib目录存放本web-app中用到的所有jar包),在classes目录中搜索*.class文件(为打包的的字节码文件);它将遍历WEB-INF目录下的web.xml配置文件,根据文件中的Servlet标签下Servlet-class子标签的内容加载相应的class文件;
(2)tomacat安装的根目录下的common目录的子目录lib中存放webapps目录下所有web-app的公共jar包,当web-app使用jar包时首先搜索本app中的lib,如果没有找到需要的jar包,将在common目录的lib中找jar包;
(3)web服务器启动时加载Servlet实现类的方法(配置WEB-INF目录下的web.xml)
在web.xml文件中与Servlet实现类相对应的Servlet标签中添加子标签,如:
<load-on-startup>1</load-on-startup>
标签内部的文本应是正整数,当多个Servlet实现类相对应的Servlet标签都添加了子标签时,根据该文本对应整数之的大小加载相应的Servlet实现类;整数值越小,加载顺序越靠前;值相等时,加载顺序由web-server决定。
3,步骤二:Servlet对象的创建与初始化
(1)大多数web-server会在客户端第一次访问服务器时加载Servlet实现类,创建对象并执行初始化方法,(如果设置服务器启动时加载,则服务器启动时创建对象并执行初始化方法,客户端第一次访问服务器时,直接进入service阶段执行service方法)一个Servlet对象的初始化方法只执行一次;
(2)当Servlet对象初始化失败,即执行init()方法抛出ServletException异常,Servlet对象将会被垃圾回收器回收,当客户端第一次访问服务器时加载Servlet实现类,创建对象并执行初始化方法;
(3)为Servlet对象设置初始化参数(配置WEB-INF目录下的web.xml)
1> 在web.xml文件中与Servlet实现类相对应的Servlet标签中添加子标签,如:
<init-param>
<param-name>参数名</param-name>
<param-name>参数值</param-value>
</init-param>
每对init-param标签只能设置一个初始化参数,如果要设置多个初始化参数,需重复以上四行代码;
2> Servlet实现类中覆盖无参的init()方法,方法内部使用getInitParameter("参数名")获得相应的参数值,该方法在javax.Servlet.ServletConfig,javax.Servlet.GenericServlet两个类中都有定义,一般使用后者(即在Servlet实现类中直接使用getInitParameter("参数名")获得相应的参数值);
3> Servlet实现类中不能覆盖有参的init(ServletConfig)方法,可能出现空指针异常,因为在GenericServlet类中init(ServletConfig)方法中第一行初始化了config成员变量,GenericServlet类中getInitParameter("参数名") 实现了getConfig().getInitParameter("参数名");当继承的类中直接使用 getInitParameter("参数名"),故会产生空指针异常。
4> 设置初始化参数可以增强程序的灵活性,当程序需要变动时,可以直接修改配置文件(web.xml),避免了修改java文件并编译的过程;
4,步骤三:Servlet对象根据客户端的请求提供service
(1) HttpServlet类继承自Servlet的实现类javax.Servlet.GenericServlet,HttpServlet类中覆盖的service()方法完成了由一个service方法向多个方法(doGet、doPost、doDelete等方法)转换的过程,细化了service方法的功能,doGet、doPost分别表示当客户端"method”属性设置为get和post时调用;HttpServlet的子类中只需要覆盖其中的一个功能方法;
(2) Service方法会在服务器被访问时调用,Servlet对象的生命周期中service方法可能被多次调用,由于web-server启动后,服务器中公开的部分资源将处于网络中,当网络中的不同主机(客户端)并发访问服务器中的同一资源,服务器将开设多个线程处理不同的请求,多线程同时处理同一对象时,有可能出现数据并发访问的错误。
(3) 多线程同时处理同一变量时(如:对同一文件进行写操作),且有读写操作时,必须考虑是否加上同步,同步添加时,不要添加范围过大,有可能使程序变为纯粹的单线程,大大削弱了系统性能;只需要做到多个线程安全的访问相同的对象就可以了;
5, 步骤四:Servlet对象的销毁(destroy()方法)
当程序中的Servlet对象不再使用时,web-server将有可能销毁该对象,不同的web-server销毁时机不同;一个Servlet对象的销毁(destroy()方法)只执行一次;
文章出处:DIY部落(http://www.diybl.com/course/3_program/java/javajs/2008827/137757.html)