您的位置:首页 > 编程语言 > Java开发

java 代码自己实现自定义的Classloader

2012-04-21 18:01 633 查看
自己开发了一个Classloader,继承自URLClassloader,希望对大家有所帮助

它可以做一般Classloader所必须做的事情,包括

(1)根据Url加载类

(2)如果本地的用file:///协议来获得的URL里面拿字节码的时候,过滤掉file:///

(3)获取字节码

(4)根据类名查找类文件

(5)载入类

/**
* @author charles.wang
*
*/
public class CustomClassLoader extends URLClassLoader {

private FileInputStream input = null;    //文件输入流
private ByteArrayOutputStream out = null;//字节数组输出流
private String[] url = null;             //类文件加载路径
private byte[] data = null;              //类文件字节码
private String extensionName = "";       //类文件扩展名

/**
*
* @param urls : 将被加载的类的url
*/
public CustomClassLoader(URL[] urls)  throws Exception{
super(urls);
// TODO Auto-generated constructor stub
this.url = new String[urls.length];
for( int i=0;i<urls.length;i++){
this.url[i] = urls[i].toURI().toString();
}
}

public FileInputStream getInput() {
return input;
}

public void setInput(FileInputStream input) {
this.input = input;
}

public ByteArrayOutputStream getOut() {
return out;
}

public void setOut(ByteArrayOutputStream out) {
this.out = out;
}

public String[] getUrl() {
return url;
}

public void setUrl(String[] url) {
this.url = url;
}

public byte[] getData() {
return data;
}

public void setData(byte[] data) {
this.data = data;
}

public String getExtensionName() {
return extensionName;
}

public void setExtensionName(String extensionName) {
this.extensionName = extensionName;
}

/**
* 解析URL,将file头去掉
*/
private void setFilePath(){
for( int i=0; i<this.url.length;i++){
if ( this.url[i].substring(0,4).toLowerCase().equals("file") == true){
this.url[i] = this.url[i].substring(5);
}
}
}

/**
* 获得指定类名(全限定类名)文件的字节码
*/
private byte[] getFileData(String name){
try{
this.setFilePath();
for(String url: this.url){
String fileName = url + name.replace(".","\\").concat(".")+ this.getExtensionName();
input = new FileInputStream( new File(fileName));
if(input != null){
break;
}
}

out = new ByteArrayOutputStream();
data = new byte[1024];
int len = -1;
while ( (len = input.read(data))  != -1){
out.write(data,0,len);
}
data = out.toByteArray();
}catch(Exception e){
e.printStackTrace();
}finally{
try {
if (input != null)
input.close();
if (out != null)
out.close();
return data;
}catch (Exception e){
e.printStackTrace();
return null;
}
}

}

/**
* 根据指定的类名查找类文件
* @param name
* @return
*/
protected Class findClassByName (String name){
try{
byte [] data = this.getFileData(name);
if (data == null){
return null;
}
return this.defineClass(name, data, 0,data.length);
}catch (Exception e){
e.printStackTrace();
return null;
}
}

/**
* 重新写 loadClass() 方法
*/
public Class loadClass (String name){
Class c = null;
try{
c = super.loadClass(name);
}catch (ClassNotFoundException e){
e.printStackTrace();
}finally {
if (c ==null ){
//父类的默认方法没有加载到指定类的话,那么使用自定义的方法去查找
c = this.findClassByName(name);
}
return c;
}
}

}


补上使用代码:

/**
* @author charles.wang
*
*/
public class MainTest {

/**
* @param args
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
URL[] url = new URL[]{new URL("file:d:\\")};
//添加想要加载的类路径,网络或者本地均可
CustomClassLoader csl = new CustomClassLoader(url);
csl.setExtensionName("class");
Class cl = csl.loadClass("com.Demo");
Object obj = cl.newInstance();
Method method = cl.getMethod("printText", null);
method.invoke(obj, null);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Classloader
相关文章推荐