1. 试用系统类加载器载入某个Servlet类所使用的全部类,那么Servlet就能够访问所有的类,包括当前运行的Java虚拟机(Java Virtual Machine,JVM)中环境CLASSPATH指明的路径下的所有的类和库。这是非常危险的。
2. Servlet应该只允许载入WEB-INF/classes目录及其子目录下的类,和从部署的库到WEB-INF/lib目录载入类。
3. Tomcat中需要实现自定义类载入其的另一个原因是,为了提供自动重载的功能,即当WEB-INF/classes目录或WEB-INF/lib目录下的类变化时,web应用会重新载入这些类。
4. 要实现自动重载功能,则载入器必须实现org.apache.catalina.loader.Reloader接口。
5. 从J2SE 1.2 开始,JVM使用了3种类加载器来载入所需要的类,分别是引导类载入器(bootstrap class loader)、扩展类载入器(extension class loader)和系统类载入器(system class loader).3种类载入器是父子关系。其中引导类载入器位于层析结构的最上层,系统类加载器位于系统的最下层。
6. 引导类加载器用于引导启动java虚拟机。当调用javax.java 程序时,就会启动引导类加载器。引导类加载器是试用本地代码实现的,因为它用来载入运行JVM所需要的类,以及所有的java核心类,例如java.lang和java.io包下的类。
7. 扩展类载入器负责载入标准的扩展目录中的类,这有利于程序的开发,因为程序员只需要将jar文件复制到扩展目录中的类,这有利于程序的开发,因为程序员只需要将jar文件复制到扩展目录下就可以被类载入器搜索到。扩展库以来与JDK供应商的具体实现,Sun公司的JVM的扩展目录是/jdk/jre/lib/ext.
8. 系统类加载器是默认的类加载器,它会搜索在环境变量CLASSPATH中指明的路径以及JAR文件。
9. 没当需要载入一个类的时候,会首先调用系统类载入器。但是,它并不会立即载入某个类。相反,它会将载入类的任务交给其父载入器,及扩展类载入器,而扩展类载入器又会将载入的任务交给其父类加载器,即引导类加载器。如果引导类加载器加载不到类,就会调用扩展类加载器加载,扩展类加载不到的话就会调用系统类加载器。如果都加载不到这个类的话就会抛出java.lang.ClassNotFoundException异常。以上这个是JVM的代理模型。
10. 设计以上代理模型的一个目的就是为了解决类加载过程中的安全问题。那么为什么使用这样的代理模型呢?举个例子:当程序中的某个地方调用了自定义的java.lang.Object允许被载入,安全管理器会轻易的被绕过(?),使用了代理模型,就会调用父类加载器来加载核心的java类。这样就不会加载自定义java.lang.Object类了。
11. 关于java中类载入机制中的一件重要的事情是,可以通过继承抽象类java.lang.CLassLoader类编写自己的类载入器。而tomcat要使用自定义的类载入器的原因有一下3条:
a) 为了在载入类中指定某些规则
b) 为了缓存已经载入的类
c) 为了实现类的预载入,方便使用。
12. Web应用程序中的WEB-INF/classes目录和WEB-INF/lib目录是作为仓库加到载入器的。
13. 载入器一般都是与Context级别的Servlet容器进行关联,并且通过Context的reload方法来实现。通过设置setReloadable()方法和getReloadable()方法,用来指明是否支持载入器的自动重载。默认情况下,在Context接口的标准实现中,是禁用了自动重载的功能的。要想启用Context容器的自动重载功能,需要在Server.xml文件中添加一个Context元素:
<context path=”/myapp” docBase=”myApp”debug=”0” reloadable=”true”/>
14. Catalina 提供了org.apache.catalina.loader.WebappLoader类作为loader接口的实现。其中,WebappLoader对象中使用org.apache.catalina.loaderWebappClassLoader类的实例作为其类载入器,该类继承自java.net.URLClassLoader类。
15. 为了支持类的自动重载功能,类载入器实现需要实现org.apache.catalina.loader.Reloader接口。
16. WebappLoader类实现了java.lang.Runnable接口,这样就可以指定一个线程来不断的调用器类载入器的modified()方法。如果Modified方法返回true,WebappLoader的实例会通知其相关联的Servlet容器。由Context容器来完成类的重新载入。
17. 当调用WebappLoader类的start方法时,会完成以下几项重要的工作:
A) 创建一个类载入器
B) 设置仓库
C) 设置类路径
D) 设置访问权限
E) 启动一个新线程来支持自动重载
18. WebappLoader只提供了getClassLoader()方法,并没有相应的setClassLoader()方法,所以设置自己定制的classLoader可以通过setLoaderClass方法做到,setLoaderClass维护了一个字符串指明了要实例化的ClassLoader的路径。这个方法是通过createClassLoader来完成实例化的。
19. 可以不使用WebappClassLoader类的实例,而使用其他类的实例作为类载入器。但是请注意,createClassLoader()方法的返回值是WebappClassLoader类型的。因此,如果定义类载入器没有继承自WebClassLoader类,createClassLoader()会抛出一个异常。异常肯定是ClassCastException.
20. WebappLoader类支持自动重载功能。如果WEB-INF/class目录或者WEB-INF/lib目录下的某些类被重新编译了,那么这个类会自动重新载入,而无需重启tomcat。为了实现此目的,WebappLoader类使用了一个线程周期性的检查每个资源的时间戳。
21. 为了达到更好的性能,会缓存已经载入的类,这样下次再使用该类时,会直接从缓存中获取。
22. 所有已经缓存的类会存储在一个名为resourceEntries的HashMap类型的变量中,其key值就是载入的资源的名称。那些载入失败的类被存储在另一个名为notFoundResource的hashMap中。
23. 一个tomcat Loader代表了一个web应用的loader而不是一个class loader。一个tomcat loader一定要实现org.apache.catalina.Loader接口。
24. Tomcat提供了两种类加载器提供使用,一种是标准的类加载器StandardClassLoader,用以实例化commonLoader、catalinaLoader、sharedLoader,在org.apache.catalina.loader.StandardClassLoader定义,它不提供热部署功能;另一种是专为web程序所提供的webClassLoader,它用以实例化为各种不熟项目的类加载 器,在org.apache.catalina.loader.WebappClassLoader定义,提供热部署功能,也就是发生classLoader搜索路径下的资源改变后,服务器重新加载。
25. Tomcat6的服务器配置文件放在 ${tomcat6}/conf目录底下。我们可以在这里找到server.xml和context.xml。当然,还有其他一些资源配置文件。在tomcat6版本中,context元素已经从server.xml文件中独立出来了,放在一个context.xml文件中。因为server.xml是不可动态重载的资源,服务器一旦启动了之后,要修改这个文件,就得重启服务器才能重新加载。而context.xml文件则不然,tomcat服务器会定时扫描这个文件。一旦发现文件被修改(时间戳变了),就会自动重新加载这个文件,而不需要重启服务器。