ClassLoader 深入解析学习笔记(五)

既然自定义加载器可以加载我们本地中的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());
    }

}

这里写图片描述
成功加载!

猜你喜欢

转载自blog.csdn.net/whandgdh/article/details/80344456