既然自定义加载器可以加载我们本地中的class文件或者jar,那它可以访问网络上的资源吗,答案是肯定的,本实例会实现自定义加载器去访问web工程上面class文件。
自定义加载器 NetFileClassLoader ,其实与加载本地文件不同的只是将class类的路径转换为了URL。其他完全样。
package main;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
public class NetFileClassLoader extends ClassLoader {
private String netPath;
public NetFileClassLoader(String path){
this.netPath=path;
}
@Override
public Class <?>findClass(String className) throws ClassNotFoundException{
Class clazz=null;
String path=ClassNameToPath(className);
byte []classData=getClassData(path);
if(classData==null){
throw new ClassNotFoundException();
}
clazz=defineClass(classData, 0, classData.length);
return clazz;
}
public String ClassNameToPath(String className){
return netPath+className.replace(".", "/")+".class";
}
public byte[]getClassData(String path){
InputStream is=null;
ByteArrayOutputStream baos=null;
URL url=null;
try {
url=new URL(path);
is=url.openStream();
baos=new ByteArrayOutputStream();
int len=-1;
byte []buffer=new byte[1024];
while((len=is.read(buffer))!=-1){
baos.write(buffer,0,len);
}
return baos.toByteArray();
} catch (Exception e) {
}finally {
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(baos!=null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
}
新建web工程loadNetFile,创建空白的工程即可,启动后,只要能通过http://127.0.0.1:8080/loadNetFile/访问即可。这里是将工程部署到tomcat上。
关键是我们需要加载的文件的位置要放正确。放到启动的web工程上面,即放到tomcat服务器上,不能放到web-info里面,不然会访问不到,只需放到工程名下即可:
NetFile.java代码非常简单:就一个toString方法
package com.test;
public class NetFile
{
public String toString()
{
return "加载网络资源文件:NetFile";
}
}
接下来从dos进入到NetFile.java路径,同样因为有中文,编译时加上编码,避免乱码:
javac -encoding utf-8 NetFile.java
编译后进行测试,测试代码如下:
package test;
import org.junit.Test;
import main.NetFileClassLoader;
public class NetFileClassLoaderTest {
@Test
public void test() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
String rootdir="http://127.0.0.1:8080/loadNetFile/netFile/";
String className="com.test.NetFile";
NetFileClassLoader classloader=new NetFileClassLoader(rootdir);
Class clazz=classloader.loadClass(className);
System.out.println(className+"的加载器是:"+clazz.getClassLoader());
System.out.println(clazz.newInstance().toString());
}
}
成功加载!