自定义ClassLoader

来源:互联网 发布:使用weka进行数据挖掘 编辑:程序博客网 时间:2024/05/19 10:09

Java 中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由 Java 应用开发人员编写的。系统提供的类加载器主要有下面三个:

  • 引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自java.lang.ClassLoader
  • 扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
  • 系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过ClassLoader.getSystemClassLoader()来获取它。

一般情况下,系统提供的类加载器可以满足通常的应用需求。如果需要特殊的需求,如从工具动态生成的或者从网络上加载字节码文件,则需要定制自己的类加载器。用户自定义类加载器可以通过继承抽象类ClassLoader实现。以下是一个网络类加载器,负责加载从网上下载的字节码文件。

Java代码 复制代码 收藏代码
  1. package classloader;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.InputStream;
  4. import java.net.URL;
  5. public class NetworkClassLoaderextends ClassLoader {
  6. private String rootUrl;
  7. public NetworkClassLoader(String rootUrl) {
  8. this.rootUrl = rootUrl;
  9. }
  10. protected Class<?> findClass(String name) throws ClassNotFoundException {
  11. byte[] classData = getClassData(name);
  12. if (classData == null) {
  13. throw new ClassNotFoundException();
  14. }
  15. else {
  16. return defineClass(name, classData, 0, classData.length);
  17. }
  18. }
  19. private byte[] getClassData(String className) {
  20. String path = classNameToPath(className);
  21. try {
  22. URL url = new URL(path);
  23. InputStream ins = url.openStream();
  24. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  25. int bufferSize = 4096;
  26. byte[] buffer = newbyte[bufferSize];
  27. int bytesNumRead = 0;
  28. while ((bytesNumRead = ins.read(buffer)) != -1) {
  29. baos.write(buffer, 0, bytesNumRead);
  30. }
  31. return baos.toByteArray();
  32. } catch (Exception e) {
  33. e.printStackTrace();
  34. }
  35. return null;
  36. }
  37. private String classNameToPath(String className) {
  38. return rootUrl + "/"
  39. + className.replace('.', '/') +".class";
  40. }
  41. }

原创粉丝点击