package org.apache.catalina;
import java.beans.PropertyChangeListener;
public interface Loader {
public ClassLoader getClassLoader();
public Container getContainer(); //載入器通常與一個context級別的容器相聯
public void setContainer(Container container);
public DefaultContext getDefaultContext();
public void setDefaultContext(DefaultContext defaultContext);
public boolean getDelegate(); //Delegate 代表 委托
public void setDelegate(boolean delegate); //就是類加載器是否會把加載的任務委托給其父類加載器
public String getInfo();
public boolean getReloadable(); //表明是否支持載入器的自動重載
public void setReloadable(boolean reloadable);
public void addPropertyChangeListener(PropertyChangeListener listener);
public void addRepository(String repository);
public String[] findRepositories();
public boolean modified(); //如果容器中的一個或多個類被修改了 modified就會返回true
public void removePropertyChangeListener(PropertyChangeListenerlistener);
}

private WebappClassLoader createClassLoader()
throws Exception {
//loadClass為字符串
//默認為 private String loaderClass =org.apache.catalina.loader.WebappClassLoader;
//可通過setLoadClass方法更改
Class clazz = Class.forName(loaderClass);
WebappClassLoader classLoader = null;
//在構造WebAppLoader時 又構造函數的參數指定
if (parentClassLoader == null) {
// Will cause a ClassCast is the class does not extend WCL, but
// this is on purpose (the exception will be caught and rethrown)
classLoader = (WebappClassLoader) clazz.newInstance();
} else {
Class[] argTypes = { ClassLoader.class };
Object[] args = { parentClassLoader };
Constructor constr = clazz.getConstructor(argTypes);
classLoader = (WebappClassLoader) constr.newInstance(args);
}
return classLoader;
}
public void run() {
if (debug >= 1)
log(BACKGROUND THREAD Starting);
// Loop until the termination semaphore is set
//整段代碼包含在while循環中
//在前面threadDone已經被設置為false
//直到程序關閉時,threadDone才會變為true
while (!threadDone) {
// Wait for our check interval
threadSleep();
if (!started)
break;
try {
// Perform our modification check
if (!classLoader.modified())
continue;
} catch (Exception e) {
log(sm.getString(webappLoader.failModifiedCheck), e);
continue;
}
// Handle a need for reloading
notifyContext();
break;
}
if (debug >= 1)
log(BACKGROUND THREAD Stopping);
}
private void threadSleep() { //讓程序休眠一段時間 時間由checkInterval指定
try {
Thread.sleep(checkInterval * 1000L);
} catch (InterruptedException e) {
;
}
}
private void notifyContext() {
WebappContextNotifier notifier = new WebappContextNotifier();
(new Thread(notifier)).start();
}
protected class WebappContextNotifier implements Runnable {
/**
* Perform the requested notification.
*/
public void run() {
((Context) container).reload();
}
}
WebappContextNotifier是webapploader的內部類。
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
};
為了達到更好的性能,會緩存已經載入的類,這樣一來下次在使用這個類的時候,就不用再起加載了。
緩存分兩級,一級在本地執行,由webappclassloader實例來管理。
package org.apache.catalina.loader;
import java.net.URL;
import java.security.cert.Certificate;
import java.util.jar.Manifest;
public class ResourceEntry {
public long lastModifled = -1;
// Binary content of the resource.public byte[] binaryContent = null;
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;
public Manifest manifest = null;
public Certificate[] certificates = null;
}