ClassLoader加载Tomcat的依赖
通过查看catalina.bat中设置的classpath只有
bootstrap.jar和tomcat-juli.jar,这两个都只包含Bootstrap执行时所需要的类,所以如果要进行后续操作,都需要再加载。通过前面返回的ClassLoader加载
1.在BootStrap中加载完成ClassLoader之后就回到了init方法中.
Thread.currentThread().setContextClassLoader(catalinaLoader);
SecurityClassLoad.securityClassLoad(catalinaLoader);
这里就开始加载tomcat所需要的class
2.进入SecurityClassLoad.securityClassLoad
public static void securityClassLoad(ClassLoader loader)
throws Exception {
if( System.getSecurityManager() == null ){
return;
}
loadCorePackage(loader);
loadCoyotePackage(loader);
loadLoaderPackage(loader);
loadRealmPackage(loader);
loadSessionPackage(loader);
loadUtilPackage(loader);
loadValvesPackage(loader);
loadJavaxPackage(loader);
loadConnectorPackage(loader);
loadTomcatPackage(loader);
}
就可以大概看出加载class的顺序了,各个方法里面都是加载指定的Class,也就是要加载那些类都写死了,如果我们要做什么扩展,只是把写好的类扔到包中,应该就会出问题。。
###总结###
1.对于tomcat自己要使用的类都是指定类名进行加载的
2.在查看启动时classpath的设置过程中,反编译了一下生成的BootStrap.class,和源码相比发现其中少import了一个的类:org.apache.catalina.Globals,开始还以为是在编译过程中做了什么处理,最后查看这个类是final的,再到网上一查,原来在编译时会对final做优化,会把final变量名直接替换成其相应的值,然后自己也做了一个小测试,确实如此。。。。看来以前疏忽了。。。
3.在回头查看ClassLoader的过程中,发现每个Class都会先判断,也就是已经加载了的,就不会再加载
Class c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
long t1 = System.nanoTime();
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
先调用了findLoadedClass,如果没有,才继续查找
来源:oschina
链接:https://my.oschina.net/u/567671/blog/186941