WebappClassLoader 继承了URLClassLoader里面加入缓存和安全。
缓存:
1.缓存了已经事先装载的Classes。
2.缓存了错误信息,比如先前装载一个类报错,那么下次再load这个类的时候,就会到缓存中去查找
( ClassNotFoundException
)
/**
* Load the class with the specified name. This method searches for
* classes in the same manner as <code>loadClass(String, boolean)</code>
* with <code>false</code> as the second argument.
*
* @param name Name of the class to be loaded
*
* @exception ClassNotFoundException if the class was not found
*/
public Class loadClass(String name) throws ClassNotFoundException {
return (loadClass(name, false));
}
/**
* Load the class with the specified name, searching using the following
* algorithm until it finds and returns the class. If the class cannot
* be found, returns <code>ClassNotFoundException</code>.
* <ul>
* <li>Call <code>findLoadedClass(String)</code> to check if the
* class has already been loaded. If it has, the same
* <code>Class</code> object is returned.</li>
* <li>If the <code>delegate</code> property is set to <code>true</code>,
* call the <code>loadClass()</code> method of the parent class
* loader, if any.</li>
* <li>Call <code>findClass()</code> to find this class in our locally
* defined repositories.</li>
* <li>Call the <code>loadClass()</code> method of our parent
* class loader, if any.</li>
* </ul>
* If the class was found using the above steps, and the
* <code>resolve</code> flag is <code>true</code>, this method will then
* call <code>resolveClass(Class)</code> on the resulting Class object.
*
* @param name Name of the class to be loaded
* @param resolve If <code>true</code> then resolve the class
*
* @exception ClassNotFoundException if the class was not found
*/
public Class loadClass(String name, boolean resolve)
throws ClassNotFoundException {
if (log.isDebugEnabled())
log.debug("loadClass(" + name + ", " + resolve + ")");
Class clazz = null;
// Log access to stopped classloader
if (!started) {
try {
throw new IllegalStateException();
} catch (IllegalStateException e) {
log.info(sm.getString("webappClassLoader.stopped", name), e);
}
}
// (0) Check our previously loaded local class cache
//在这里装载的时候使用了缓存,注意这个是local class
clazz = findLoadedClass0(name);
if (clazz != null) {
if (log.isDebugEnabled())
log.debug(" Returning class from cache");
if (resolve)
resolveClass(clazz);
return (clazz);
}
// (0.1) Check our previously loaded class cache
//而这个就是class
clazz = findLoadedClass(name);
if (clazz != null) {
if (log.isDebugEnabled())
log.debug(" Returning class from cache");
if (resolve)
resolveClass(clazz);
return (clazz);
}
// (0.2) Try loading the class with the system class loader, to prevent
// the webapp from overriding J2SE classes
try {
clazz = system.loadClass(name);
if (clazz != null) {
if (resolve)
resolveClass(clazz);
return (clazz);
}
} catch (ClassNotFoundException e) {
// Ignore
}
// (0.5) Permission to access this class when using a SecurityManager
//安全机制
if (securityManager != null) {
int i = name.lastIndexOf('.');
if (i >= 0) {
try {
securityManager.checkPackageAccess(name.substring(0,i));
} catch (SecurityException se) {
String error = "Security Violation, attempt to use " +
"Restricted Class: " + name;
log.info(error, se);
throw new ClassNotFoundException(error, se);
}
}
}
boolean delegateLoad = delegate || filter(name);
// (1) Delegate to our parent if requested
//代理装载类
if (delegateLoad) {
if (log.isDebugEnabled())
log.debug(" Delegating to parent classloader1 " + parent);
ClassLoader loader = parent;
if (loader == null)
loader = system;
try {
clazz = loader.loadClass(name);
if (clazz != null) {
if (log.isDebugEnabled())
log.debug(" Loading class from parent");
if (resolve)
resolveClass(clazz);
return (clazz);
}
} catch (ClassNotFoundException e) {
;
}
}
// (2) Search local repositories
if (log.isDebugEnabled())
log.debug(" Searching local repositories");
try {
clazz = findClass(name);
if (clazz != null) {
if (log.isDebugEnabled())
log.debug(" Loading class from local repository");
if (resolve)
resolveClass(clazz);
return (clazz);
}
} catch (ClassNotFoundException e) {
;
}
// (3) Delegate to parent unconditionally
if (!delegateLoad) {
if (log.isDebugEnabled())
log.debug(" Delegating to parent classloader at end: " + parent);
ClassLoader loader = parent;
if (loader == null)
loader = system;
try {
clazz = loader.loadClass(name);
if (clazz != null) {
if (log.isDebugEnabled())
log.debug(" Loading class from parent");
if (resolve)
resolveClass(clazz);
return (clazz);
}
} catch (ClassNotFoundException e) {
;
}
}
throw new ClassNotFoundException(name);
}
看看WebAppClassLoader是如何从缓存中装载的
/**
* Finds the class with the given name if it has previously been
* loaded and cached by this class loader, and return the Class object.
* If this class has not been cached, return <code>null</code>.
*
* @param name Name of the resource to return
*/
protected Class findLoadedClass0(String name) {
//resouceEntries是个hashmap
ResourceEntry entry = (ResourceEntry) resourceEntries.get(name);
if (entry != null) {
return entry.loadedClass;
}
return (null); // FIXME - findLoadedResource()
}
//看看缓存对象的代码
import java.net.URL;
import java.security.cert.Certificate;
import java.util.jar.Manifest;
/**
* Resource entry.
*
* @author Remy Maucherat
* @version $Revision: 302726 $ $Date: 2004-02-27 15:59:07 +0100 (ven., 27 f茅vr. 2004) $
*/
public class ResourceEntry {
/**
* The "last modified" time of the origin file at the time this class
* was loaded, in milliseconds since the epoch.
*/
public long lastModified = -1;
/**
* Binary content of the resource.
*/
public byte[] binaryContent = null;
/**
* Loaded class.
*/
public Class loadedClass = null;
/**
* URL source from where the object was loaded.
*/
public URL source = null;
/**
* URL of the codebase from where the object was loaded.
*/
public URL codeBase = null;
/**
* Manifest (if the resource was loaded from a JAR).
*/
public Manifest manifest = null;
/**
* Certificates (if the resource was loaded from a JAR).
*/
public Certificate[] certificates = null;
}
安全机制
/**
* The set of trigger classes that will cause a proposed repository not
* to be added if this class is visible to the class loader that loaded
* this factory class. Typically, trigger classes will be listed for
* components that have been integrated into the JDK for later versions,
* but where the corresponding JAR files are required to run on
* earlier versions.
*/
protected static final String[] triggers = {
"javax.servlet.Servlet" // Servlet API
};
//这个在Tomcat4中有,在tomcat6.0中没有
private static final String[] packageTriggers = {
"javax", // Java extensions
"org.xml.sax", // SAX 1 & 2
"org.w3c.dom", // DOM 1 & 2
"org.apache.xerces", // Xerces 1 & 2
"org.apache.xalan" // Xalan
};
分享到:
相关推荐
3. "理解Tomcat的WebappClassLoader(web应用类加载器)一.doc":进一步探讨WebappClassLoader的工作机制,包括类查找策略、双亲委派模型的实现及其在多web应用环境下的应用。 4. "Tomcat源码分析(4)容器处理链接之...
主要有CommonClassLoader、SharedClassLoader和WebappClassLoader,它们按层次加载类。 5. **连接器(Connector)与协议处理器(Protocol Handler)** - **Coyote Connector**:Tomcat的Coyote组件负责接收和发送...
7. **使用隔离的类加载器**:通过设置不同的类加载策略,例如Web应用的`WebappClassLoader`,可以避免不同应用之间的jar冲突。 8. **社区支持**:在Apache Tomcat的官方论坛或Stack Overflow等技术社区提问,获取...
2. **类加载机制**:Tomcat使用自定义的类加载器,如`CommonClassLoader`、`WebappClassLoader`等,以实现不同Web应用间的隔离。 3. **请求处理**:` CoyoteAdapter`是Servlet容器与Tomcat网络接口(Coyote)之间的...
`WebappClassLoader`则负责加载应用的类和资源文件。 四、线程模型 Tomcat采用基于线程池的并发模型,`Executor`接口及其实现类`ThreadPoolExecutor`用于管理线程。默认情况下,Tomcat使用`AprLifecycleListener`...
理解`org.apache.catalina.loader`包下的`WebappClassLoader`及其工作原理,是深入理解Tomcat多应用隔离的关键。 6. **线程池和并发模型**:Tomcat使用线程池处理请求,以提高并发性能。理解`Executor`和线程管理...
- `-Dorg.apache.catalina.loader.WebappClassLoader.ENABLE_CLEAR_REFERENCES=false`:解决Tomcat重新加载Web应用时,不清除class文件中static和final变量的值而导致的潜在问题。 - `-Duser.timezone=GMT+08`:...
12. **类加载及对象回收**:了解Tomcat的类加载机制(如WebAppClassLoader),并使用JVM工具跟踪对象创建和销毁。 13. **请求处理过程**:一个完整的请求从HTTP客户端发起,经过网络传输到达Tomcat,被Connector...
一旦检测到变化,Tomcat会停止应用的启动线程,清除引用,并将加载该应用的WebappClassLoader置为null,然后创建一个新的WebappClassLoader实例重新加载应用。 在Maven工程中配置Tomcat热部署,需要在pom.xml文件中...
Tomcat作为一款广泛使用的Java应用服务器,其类加载机制有着独特的设计,特别是对Java的双亲委派模型有所突破。本篇文章将深入探讨Tomcat如何打破双亲委派模型,并通过源码分析和图表解析来帮助理解这一机制。 首先...
4. **使用WebAppClassLoader**:针对特定应用的JAR,应放在Web应用的`WEB-INF/lib`下,由WebAppClassLoader加载。 **三、配置文件详解** 1. **server.xml**:这是Tomcat的主要配置文件,包含了Server、Service、...
Tomcat的类加载机制遵循“父类加载优先”原则,通过`CommonLoader`、`CatalinaLoader`、`SharedLoader`和`WebappClassLoader`四个层次进行加载,保证了不同Web应用之间的类隔离。 8. **安全性** Tomcat支持多种...
在Java的Web应用开发中,WebappClassLoader是Tomcat等Servlet容器用于加载应用中类的特定类加载器。它负责加载Web应用程序的类和资源,确保每个Web应用都有自己的类加载器实例,从而实现类的隔离。 该问题可能涉及...
Tomcat's WebappClassLoader is currently not instrumentable, so Spring provides a custom ClassLoader that can be used by placing spring-instrument-tomcat.jar in $TOMCAT_HOME/lib and putting a loader ...
Tomcat使用WebappLoader和WebappClassLoader来加载Web应用的类,并监控类的改动,实现热部署。 七、Session管理 Tomcat提供了对HTTP会话(Session)的管理,包括创建、存储和销毁Session,以及在集群环境下的...
通过阅读`WebappClassLoader`的源码,结合实际的Tomcat部署经验,我们可以更深刻地理解类加载机制,这对于解决复杂的应用问题和提升性能优化能力具有极大的帮助。在学习过程中,可以参考博客文章(如提供的链接)和...
5. **类加载**:探究`org.apache.catalina.loader.WebappClassLoader`,了解如何加载Web应用的类。 6. **部署与卸载**:了解`org.apache.catalina.manager.ManagerBase`和`org.apache.catalina.startup....