Servlet加载器的实验

时间:2023-03-08 17:48:36

今天,看了张孝祥老师的类加载器的一个高级实验分析的教程,有点受益匪浅。

新建servlet工程,在Servlet类中

package com.sinosoft.servelt;

import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import com.sun.org.apache.xml.internal.serialize.Printer; /**
* Servlet implementation class MyServlet
*/
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L; /**
* @see HttpServlet#HttpServlet()
*/
public MyServlet() {
super();
// TODO Auto-generated constructor stub
} /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out=response.getWriter();
ClassLoader loader=this.getClass().getClassLoader();
while(loader!=null){
out.print(loader.getClass().getName()+"<br>");
loader=loader.getParent();
}
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
} }

启动  tomcat目录下的bin目录下的,startup.bat,之后访问这个servlet,结果如下

Servlet加载器的实验

从图中,我们看到,类加载器的加载Myservlet这个类的顺序是,Ext加载App加载Standard加载Webapp,最终是由Webapp加载了Myservlet这个类及其继承HttpServet类(此类在tomcat的lib目录下)

现在我们,把Myservlet这个类 ,以jar包格式, export到jdk的F:\Program Files\Java\jdk1.7.0_02\jre\lib\ext目录下,这一步要注意的是,tomcat对应的jdk,和我们这次export的目录是否是同一个jdk,不确定的话,可以去tomcat的bin目录下,打开startup.bat    指定一下 set JAVA_HOME=F:\Program Files\Java\jdk1.7.0_02,否则会没有效果。

Servlet加载器的实验

Servlet加载器的实验

重启tomcat,再次访问那个url,则报出500错误,

Servlet加载器的实验

这是因为ext的那个加载器,加载了sinosoft.jar的包下的Myservlet类,但是没有Myservlet类继承的HttpServlet那个类的jar包,即servlet-api.jar包。我们去tomcat目录下的lib目录下拷贝servlet-api.jar包到F:\Program Files\Java\jdk1.7.0_02\jre\lib\ext目录下,再次重启tomcat,可以得出下面的结果

Servlet加载器的实验

也就是ext加载器,第一次就发现了有myservlet及其继承的httpservelt的字节码,便直接加载进jvm,就不再继续往后继续寻找之后的加载器了。