Servlet实例创建时刻

之前没有仔细研究这个问题,学的时候别人说Servlet实例是在web container启动时也即是服务器启动过程就new 出来。某个Servlet实例一旦new 出来,马上就会执行其init(ServletConfig sc)方法。

上面这句话,前半句是错了,后半句是正确的,这个直到今天我才发现。哇,这么久了,现在才发现这个错误,对自己感到一丝悲哀啊。。好,废话不多说,先看我做的实验,然后再分析哈源码。


实验一


准备Servlet:

package com.eabax.web.action.product;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

public class ServletTest extends HttpServlet {

	public ServletTest() {
		System.out.println("*****************************************************");
		System.out.println("new instance of class ServletTest");
		System.out.println("*****************************************************");
	}
	
	public void init() throws ServletException {
		super.init();
		System.out.println("*****************************************************");
		System.out.println("call Servlet init method");
		System.out.println("*****************************************************");
	}

}

配置web.xml:

<servlet>
        <servlet-name>test</servlet-name>
	<servlet-class>com.eabax.web.action.product.ServletTest</servlet-class>
</servlet>

<servlet-mapping>
	<servlet-name>test</servlet-name>
	<url-pattern>*.php</url-pattern>
</servlet-mapping>

部署web应用,并启动tomcat server 6.0.36,输出如下:

Jan 12, 2014 11:28:15 AM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: D:\Program Files\Java\jdk1.7.0_45\bin;E:\Installation Programs\About Java\Java tools\Tomcat server\apache-tomcat-6.0.36\bin
Jan 12, 2014 11:28:16 AM org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
Jan 12, 2014 11:28:16 AM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 1069 ms
Jan 12, 2014 11:28:16 AM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Jan 12, 2014 11:28:16 AM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.36
Jan 12, 2014 11:28:16 AM org.apache.catalina.startup.HostConfig deployDescriptor
INFO: Deploying configuration descriptor host-manager.xml
Jan 12, 2014 11:28:16 AM org.apache.catalina.startup.HostConfig deployDescriptor
INFO: Deploying configuration descriptor manager.xml
Jan 12, 2014 11:28:16 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory CqutSecondHandTradeSystem
log4j:WARN No appenders could be found for logger (org.springframework.core.CollectionFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Jan 12, 2014 11:28:18 AM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
Jan 12, 2014 11:28:25 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory docs
Jan 12, 2014 11:28:25 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory jpa_test
Jan 12, 2014 11:28:25 AM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(E:\Installation Programs\About Java\Java tools\Tomcat server\apache-tomcat-6.0.36\webapps\jpa_test\WEB-INF\lib\servlet-api.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
Jan 12, 2014 11:28:26 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory ROOT
Jan 12, 2014 11:28:26 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory tag
Jan 12, 2014 11:28:26 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory user
Jan 12, 2014 11:28:26 AM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory xhEditor
Jan 12, 2014 11:28:27 AM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Jan 12, 2014 11:28:27 AM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Jan 12, 2014 11:28:27 AM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/44  config=null
Jan 12, 2014 11:28:27 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 11329 ms
从Tomcat的启动日志信息中可以发现,并没有输出类ServletTest的的初始化代码,也就是Tomcat启动过程中并没有new 出Servlet的实例。

下面从浏览器中访问地址:http://localhost:8080/jpa_test/aaa.php ,控制台输出如下:

Jan 12, 2014 11:28:27 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 11329 ms
*****************************************************
new instance of class ServletTest
*****************************************************
*****************************************************
call Servlet init method
*****************************************************

从以上过程中,就可以发现:Servet实例的初始化时刻并非是web container启动的时候,而是第一次需要该Servlet处理请求的时候。


实验二


配置web.xml:

与实验一唯一不同的地方就是这次实验在web.xml文件中register servlet的时侯,多加了一个load-on-startup参数。如下:
	<servlet>
		<servlet-name>test</servlet-name>
		<servlet-class>com.eabax.web.action.product.ServletTest</servlet-class>
		<load-on-startup>0</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>test</servlet-name>
		<url-pattern>*.php</url-pattern>
	</servlet-mapping>

部署web应用,并启动tomcat server 6.0.36,输出如下:

Jan 13, 2014 6:12:45 PM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: D:\Program Files\Java\jdk1.7.0_45\bin;E:\Installation Programs\About Java\Java tools\Tomcat server\apache-tomcat-6.0.36\bin
Jan 13, 2014 6:12:45 PM org.apache.coyote.http11.Http11Protocol init
INFO: Initializing Coyote HTTP/1.1 on http-8080
Jan 13, 2014 6:12:45 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 960 ms
Jan 13, 2014 6:12:45 PM org.apache.catalina.core.StandardService start
INFO: Starting service Catalina
Jan 13, 2014 6:12:45 PM org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.36
Jan 13, 2014 6:12:45 PM org.apache.catalina.startup.HostConfig deployDescriptor
INFO: Deploying configuration descriptor host-manager.xml
Jan 13, 2014 6:12:46 PM org.apache.catalina.startup.HostConfig deployDescriptor
INFO: Deploying configuration descriptor manager.xml
Jan 13, 2014 6:12:46 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory CqutSecondHandTradeSystem
log4j:WARN No appenders could be found for logger (org.springframework.core.CollectionFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Jan 13, 2014 6:12:47 PM org.apache.catalina.core.ApplicationContext log
INFO: Initializing Spring root WebApplicationContext
Jan 13, 2014 6:12:54 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory docs
Jan 13, 2014 6:12:54 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory jpa_test
Jan 13, 2014 6:12:54 PM org.apache.catalina.loader.WebappClassLoader validateJarFile
INFO: validateJarFile(E:\Installation Programs\About Java\Java tools\Tomcat server\apache-tomcat-6.0.36\webapps\jpa_test\WEB-INF\lib\servlet-api.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class
*****************************************************
new instance of class ServletTest
*****************************************************
*****************************************************
call Servlet init method
*****************************************************
Jan 13, 2014 6:12:55 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory ROOT
Jan 13, 2014 6:12:55 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory tag
Jan 13, 2014 6:12:55 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory user
Jan 13, 2014 6:12:55 PM org.apache.catalina.startup.HostConfig deployDirectory
INFO: Deploying web application directory xhEditor
Jan 13, 2014 6:12:55 PM org.apache.coyote.http11.Http11Protocol start
INFO: Starting Coyote HTTP/1.1 on http-8080
Jan 13, 2014 6:12:55 PM org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
Jan 13, 2014 6:12:55 PM org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/22  config=null
Jan 13, 2014 6:12:55 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 10284 ms

从以上输出信息可见,这次tomcat在启动过程中new 出了Servlet的实例。通过上面两个实验也可以知道在register Servlet的时候,加了load-on-startup和没有加这个参数的区别了。

源码分析

做到这里,才发现分析源码就得分析Tomcat的源码,这超出了我之前的预料。于是我把Tomcat的jar包也导入工程,并attach source,试图分析源码。但是其真的很复杂,还不能做到从tomcat入口开始分析,一步一步分析程序的执行过程。所以萌生了调试tomcat的想法。于是经过查找资料,整理出了在myeclipse2013种调试tomcat的步骤。有兴趣的coder可以参考另一篇博文: MyEclipse中调试Tomcat,欢迎吐槽。

你可能感兴趣的:(servlet,Servlet生命周期)