tomcat 7自带很多junit测试用例,可以帮助我们窥探源码的秘密。以下使用来测试类加载器的一个测试用例。类加载器也是对象,他们用来将类从类从。class文件加载到虚拟机,这些已经讲了很多,深入jvm中说的很详细,什么双亲委派模型,在书中还以tomcat为例讲解。
      /*
      
       * Licensed to the Apache Software Foundation (ASF) under one or more
      
       * contributor license agreements. See the NOTICE file distributed with
      
       * this work for additional information regarding copyright ownership.
      
       * The ASF licenses this file to You under the Apache License, Version 2.0
      
       * (the "License"); you may not use this file except in compliance with
      
       * the License. You may obtain a copy of the License at
      
       *
      
       * http://www.apache.org/licenses/LICENSE-2.0
      
       *
      
       * Unless required by applicable law or agreed to in writing, software
      
       * distributed under the License is distributed on an "AS IS" BASIS,
      
       * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      
       * See the License for the specific language governing permissions and
      
       * limitations under the License.
      
       */
      
      package org.apache.catalina.loader;
    
      import java.io.File;
      
      import java.io.IOException;
      
      import java.net.URL;
      
      import java.net.URLClassLoader;
      
      import java.util.HashMap;
      
      import java.util.List;
      
      import java.util.Map;
    
      import javax.servlet.ServletException;
      
      import javax.servlet.http.HttpServlet;
      
      import javax.servlet.http.HttpServletRequest;
      
      import javax.servlet.http.HttpServletResponse;
    
      
      import org.junit.Assert;
      
      import org.junit.Test;
      
      import org.apache.catalina.core.StandardContext;
      
      import org.apache.catalina.startup.Tomcat;
      
      import org.apache.catalina.startup.TomcatBaseTest;
      
      import org.apache.tomcat.util.buf.ByteChunk;
    
public class TestWebappClassLoader extends TomcatBaseTest {
       @Test
      
       public void testGetURLs() throws Exception {
    
File f = new File("test/webresources/war-url-connection.war");
       String[] expected = new String[2];
      
       String warUrl = f.toURI().toURL().toExternalForm();
      
       expected[0] = "jar:" + warUrl + "!/WEB-INF/classes/";
      
       expected[1] = "jar:" + warUrl + "!/WEB-INF/lib/test.jar";
    
       Tomcat tomcat = getTomcatInstance();
      
       // Must have a real docBase - just use temp
      
       StandardContext ctx =
      
       (StandardContext)tomcat.addContext("", f.getAbsolutePath());
    
tomcat.start();
       //获得当前的类加载器
      
       ClassLoader cl = ctx.getLoader().getClassLoader();
      
      
    
       Assert.assertTrue(cl instanceof URLClassLoader);
      
       //获得类加载器中对应的路径
    
       try (URLClassLoader ucl = (URLClassLoader) cl) {
      
       URL[] urls = ucl.getURLs();
      
       Assert.assertEquals(expected.length, urls.length);
      
       String[] actual = new String[urls.length];
      
       for (int i = 0; i < urls.length; i++) {
      
       actual[i] = urls[i].toExternalForm();
      
       System.out.println(actual[i]);
      
       }
      
       Assert.assertArrayEquals(expected, actual);
      
       //获得类加载器的各级父类加载器
      
       while(cl!=null)
      
       {
      
       System.out.println(cl);
      
       cl=cl.getParent();
      
      
       }
      
      
      
       }
      
       }
      
       @Test
      
       public void testBug53454() throws Exception {
      
       Tomcat tomcat = getTomcatInstance();
    
       // Must have a real docBase - just use temp
      
       StandardContext ctx = (StandardContext)
      
       tomcat.addContext("", System.getProperty("java.io.tmpdir"));
      
       System.out.println("临时目录"+System.getProperty("java.io.tmdir"));
    
       // Map the test Servlet
      
       MyServlet largeBodyServlet = new MyServlet();
      
       Tomcat.addServlet(ctx, "MyServlet", largeBodyServlet);
      
       ctx.addServletMapping("/", "MyServlet");
    
tomcat.start();
       Map<String,List<String>> resHeaders= new HashMap<>();
      
       int rc = headUrl("http://localhost:" + getPort() + "/", new ByteChunk(),
      
       resHeaders);
      
    
       Assert.assertEquals(HttpServletResponse.SC_OK, rc);
      
       ClassLoader cl=ctx.getClass().getClassLoader();
      
       while(cl!=null)
      
       {
      
       System.out.println(cl);
      
       cl=cl.getParent();
      
       }
      
      
      
       }
      
       private static class MyServlet extends HttpServlet {
    
       private static final long serialVersionUID = 1L;
      
    
       @Override
      
       protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      
       throws ServletException, IOException {
      
      
      
       }
      
      
       }
      
       }
    
      
         
      
    
  输出结果:
      
        临时目录null
      
      
        
sun.misc.Launcher$AppClassLoader@4bb8d481
sun.misc.Launcher$ExtClassLoader@538787fd
      
      
        
jar:file:
      
      /F:/javal/Tomcat-Research-trunk/test/webresources/war-url-connection.war!/WEB-INF/classes/
      
        
jar:file:
      
      /F:/javal/Tomcat-Research-trunk/test/webresources/war-url-connection.war!/WEB-INF/lib/
      
        test.jar
WebappClassLoader
  context: 
  delegate: 
      
      
        false
      
      
---------->
      
         Parent Classloader:
sun.misc.Launcher$AppClassLoader@4bb8d481
sun.misc.Launcher$AppClassLoader@4bb8d481
sun.misc.Launcher$ExtClassLoader@538787fd
一月 
      
      26, 2015 6:52:56
      
         下午 org.apache.coyote.AbstractProtocol stop
INFO: Stopping ProtocolHandler [
      
      "http-nio-127.0.0.1-auto-2-64075"
      
        ]
一月 
      
      26, 2015 6:52:56
      
         下午 org.apache.coyote.AbstractProtocol destroy
INFO: Destroying ProtocolHandler [
      
      "http-nio-127.0.0.1-auto-2-64075"]
    
  
如果使用临时目录和默认目录,应用的类加载器是AppClassLoader,而其的目录可以每个应用的类加载器为WebappClassLoader


 
					 
					