自定义类加载器:
因为系统的ClassLoader只会加载指定目录下的class文件,如果你想加载自己的class文件,那么就可以自定义一个ClassLoader。而且我们可以根据自己的需求,对class文件进行加密和解密,自定义类加载器步骤如下:
- 继承抽象类ClassLoader;
- 重写findclass(String name)方法;
- 调用defineClass(String name, byte[] b, int off, int len)方法;
// 自定义类加载器
public class MyClassLoader extends ClassLoader{
/**指定加载路径*/
private String path;
public MyClassLoader(String classpath) {
path = classpath;
}
/**
*
* @param name 类的全限定名
* @return 该类的Class实例
* @throws ClassNotFoundException
*/
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
// 获取class文件的字节码数组
byte[] classByte = getClassByte(name);
if (classByte!=null){
// 将字节码数组转换成Class类实例
return defineClass(name,classByte,0,classByte.length);
}
throw new ClassNotFoundException(name);
}
/**
*
* @param name 类的全限定名
* @return class文件的字节码数组
*/
private byte[] getClassByte(String name){
String path = this.path+name.replace(".","/").concat(".class");
File file = new File(path);
if (file.exists()){
FileInputStream fis = null;
ByteArrayOutputStream baos = null;
try {
fis = new FileInputStream(file);
baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int size = 0;
while ((size=fis.read(buffer))!=-1){
baos.write(buffer,0,size);
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return baos.toByteArray();
}
return null;
}
}
// 被加载测试类
public class ClassLoaderTest {
public void say(){
System.out.println("load ClassLoaderTest class successfully!");
}
}
// 测试类
public class Test {
public static void main(String[] args) throws Exception {
MyClassLoader myClassLoader = new MyClassLoader("/Users/teihin/projects/");
String name = "com.test.ClassLoaderTest";
Class<?> classLoaderTest = myClassLoader.loadClass(name);
System.out.println("类加载器是:"+classLoaderTest.getClassLoader());
// 利用反射获取say方法
Method method = classLoaderTest.getMethod("say");
Object object = classLoaderTest.newInstance();
method.invoke(object);
}
}
// 输出结果:
类加载器是:intron.classtest.classload.MyClassLoader@1d44bcfa
load ClassLoaderTest class successfully!
Tomcat类加载器:
Tomcat 拥有不同的自定义类加载器,以实现对各种资源库的控制。一般来说,Tomcat主要用类加载器解决以下4个问题:
- 同一个Web服务器里,各个web项目之间各自使用Java类库要互相隔离;
- 同一个Web服务器里,各个Web项目之间可以提供共享的java类库;
- 为了使服务器不受web项目的影响,应该使服务器的类库与应用程序类库互相独立;
- 对于支持JSP的Web服务器,应该支持热插拔功能;