tomcat源代码学习08-06-18
在主类中有这么三个属性:protected ClassLoader commonLoader = null;
protected ClassLoader catalinaLoader = null;
protected ClassLoader sharedLoader = null;
ClassLoader 是jdk中自带的api类,那么它是一个什么样的类呢?它其实是java中的类加载器,是负责加载类的对象。ClassLoader 类是一个抽象类。如果给定类的二进制名称,那么类加载器会试图查找或生成构成类定义的数据。一般策略是将名称转换为某个文件名,然后从文件系统读取该名称的“类文件”。
String className = "java.lang.Integer";
try {
Class []parameterTypes = {int.class};
Object [] initargs = {1};
Constructor constr = ClassLoader.getSystemClassLoader().loadClass(className).getConstructor(parameterTypes);
Integer i = (Integer)constr.newInstance(initargs);
System.out.println("执行完毕:"+i.longValue());
上面是我写的一段小程序来测试这个类,假如我要装载一个类,叫作:java.lang.Integer,并且该类名必须是一个二进制名称 ,按照《Java Language Specification》的定义,任何作为 String 类型参数传递给 ClassLoader 中方法的类名称都必须是一个二进制名称。
有效类名称的示例包括:
"java.lang.String"
"javax.swing.JSpinner$DefaultEditor"
"java.security.KeyStore$Builder$FileBuilder$1"
"java.net.URLClassLoader$3$1"
注意:ClassLoader是一个抽象类不能构造对象,ClassLoader.getSystemClassLoader()这个方法却可以让我们获得系统自带的类装载器,那么通过该装载器装载进来的就是jdk里的Integer类了。
例如,应用程序可以创建一个网络类加载器,从服务器中下载类文件。示例代码如下所示:
ClassLoader loader = new NetworkClassLoader(host, port);
Object main = loader.loadClass("Main", true).newInstance();
. . .
网络类加载器子类必须定义方法 findClass 和 loadClassData,以实现从网络加载类。下载组成该类的字节后,它应该使用方法 defineClass 来创建类实例。示例实现如下:
class NetworkClassLoader extends ClassLoader {
String host;
int port;
public Class findClass(String name) {
byte[] b = loadClassData(name);
return defineClass(name, b, 0, b.length);
}
private byte[] loadClassData(String name) {
// load the class data from the connection
. . .
}
}
但是,如果我自己来定义个ClassLoader的具体子类,并且用该子类构造的对象来装载我自己的类,同样装载java.lang.Integer就可以获得一个不同的类了。改类的class字节流可能来自于文件系统,也可以来自己网络的某个环境,这就非常好了。
回到tomcat源代码,它定义这么三个类来装载实际上就是用自己的方式来装载类。
页:
[1]