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

简介:

 自己开发了一个Classloader,继承自URLClassloader,希望对大家有所帮助

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

(1)根据Url加载类

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

(3)获取字节码

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

(5)载入类

 

 

 
 
  1. /** 
  2.  * @author charles.wang 
  3.  * 
  4.  */ 
  5. public class CustomClassLoader extends URLClassLoader { 
  6.  
  7.     private FileInputStream input = null;    //文件输入流 
  8.     private ByteArrayOutputStream out = null;//字节数组输出流 
  9.     private String[] url = null;             //类文件加载路径 
  10.     private byte[] data = null;              //类文件字节码 
  11.     private String extensionName = "";       //类文件扩展名 
  12.      
  13.     /** 
  14.      * 
  15.      * @param urls : 将被加载的类的url 
  16.      */ 
  17.     public CustomClassLoader(URL[] urls)  throws Exception{ 
  18.         super(urls); 
  19.         // TODO Auto-generated constructor stub 
  20.         this.url = new String[urls.length]; 
  21.         forint i=0;i<urls.length;i++){ 
  22.             this.url[i] = urls[i].toURI().toString(); 
  23.         } 
  24.     } 
  25.      
  26.      
  27.     public FileInputStream getInput() { 
  28.         return input; 
  29.     } 
  30.  
  31.  
  32.     public void setInput(FileInputStream input) { 
  33.         this.input = input; 
  34.     } 
  35.  
  36.  
  37.     public ByteArrayOutputStream getOut() { 
  38.         return out; 
  39.     } 
  40.  
  41.  
  42.     public void setOut(ByteArrayOutputStream out) { 
  43.         this.out = out; 
  44.     } 
  45.  
  46.  
  47.     public String[] getUrl() { 
  48.         return url; 
  49.     } 
  50.  
  51.  
  52.     public void setUrl(String[] url) { 
  53.         this.url = url; 
  54.     } 
  55.  
  56.  
  57.     public byte[] getData() { 
  58.         return data; 
  59.     } 
  60.  
  61.  
  62.     public void setData(byte[] data) { 
  63.         this.data = data; 
  64.     } 
  65.  
  66.  
  67.     public String getExtensionName() { 
  68.         return extensionName; 
  69.     } 
  70.  
  71.  
  72.     public void setExtensionName(String extensionName) { 
  73.         this.extensionName = extensionName; 
  74.     } 
  75.      
  76.      
  77.      
  78.      
  79.     /** 
  80.      * 解析URL,将file头去掉 
  81.      */ 
  82.     private void setFilePath(){ 
  83.         forint i=0; i<this.url.length;i++){ 
  84.             if ( this.url[i].substring(0,4).toLowerCase().equals("file") == true){ 
  85.                 this.url[i] = this.url[i].substring(5); 
  86.             } 
  87.         } 
  88.     } 
  89.          
  90.     /** 
  91.      * 获得指定类名(全限定类名)文件的字节码 
  92.      */ 
  93.     private byte[] getFileData(String name){ 
  94.         try
  95.             this.setFilePath(); 
  96.             for(String url: this.url){ 
  97.                 String fileName = url + name.replace(".","\\").concat(".")+ this.getExtensionName(); 
  98.                 input = new FileInputStream( new File(fileName)); 
  99.                 if(input != null){ 
  100.                     break
  101.                 }            
  102.             } 
  103.              
  104.             out = new ByteArrayOutputStream(); 
  105.             data = new byte[1024]; 
  106.             int len = -1
  107.             while ( (len = input.read(data))  != -1){ 
  108.                 out.write(data,0,len); 
  109.             } 
  110.             data = out.toByteArray(); 
  111.         }catch(Exception e){ 
  112.             e.printStackTrace(); 
  113.         }finally
  114.             try { 
  115.                 if (input != null
  116.                     input.close(); 
  117.                 if (out != null
  118.                     out.close(); 
  119.                 return data; 
  120.             }catch (Exception e){ 
  121.                 e.printStackTrace(); 
  122.                 return null
  123.             } 
  124.         } 
  125.      
  126.     } 
  127.      
  128.     /** 
  129.      * 根据指定的类名查找类文件 
  130.      * @param name 
  131.      * @return 
  132.      */ 
  133.     protected Class findClassByName (String name){ 
  134.         try
  135.             byte [] data = this.getFileData(name); 
  136.             if (data == null){ 
  137.                 return null
  138.             } 
  139.             return this.defineClass(name, data, 0,data.length); 
  140.         }catch (Exception e){ 
  141.             e.printStackTrace(); 
  142.             return null
  143.         } 
  144.     } 
  145.      
  146.     /** 
  147.      * 重新写 loadClass() 方法 
  148.      */ 
  149.     public Class loadClass (String name){ 
  150.         Class c = null
  151.         try
  152.              c = super.loadClass(name); 
  153.         }catch (ClassNotFoundException e){ 
  154.             e.printStackTrace(); 
  155.         }finally { 
  156.             if (c ==null ){ 
  157.                 //父类的默认方法没有加载到指定类的话,那么使用自定义的方法去查找 
  158.                 c = this.findClassByName(name); 
  159.             } 
  160.             return c; 
  161.         } 
  162.     } 
  163.      
  164.      

 

补上使用代码:

 

 
 
  1. /** 
  2.  * @author charles.wang 
  3.  * 
  4.  */ 
  5. public class MainTest { 
  6.  
  7.     /** 
  8.      * @param args 
  9.      */ 
  10.     public static void main(String[] args) throws Exception { 
  11.         // TODO Auto-generated method stub 
  12.         URL[] url = new URL[]{new URL("file:d:\\")}; 
  13.         //添加想要加载的类路径,网络或者本地均可 
  14.         CustomClassLoader csl = new CustomClassLoader(url); 
  15.         csl.setExtensionName("class"); 
  16.         Class cl = csl.loadClass("com.Demo"); 
  17.         Object obj = cl.newInstance(); 
  18.         Method method = cl.getMethod("printText"null); 
  19.         method.invoke(obj, null); 
  20.     } 
  21.  




本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/840714,如需转载请自行联系原作者

目录
相关文章
|
7天前
|
Java 测试技术 应用服务中间件
常见 Java 代码缺陷及规避方式(下)
常见 Java 代码缺陷及规避方式(下)
27 0
|
9天前
|
Java
Java中ReentrantLock释放锁代码解析
Java中ReentrantLock释放锁代码解析
25 8
|
12天前
|
前端开发 小程序 Java
uniapp上传图片 前端以及java后端代码实现
uniapp上传图片 前端以及java后端代码实现
28 0
|
7天前
|
Java
代码的魔法师:Java反射工厂模式详解
代码的魔法师:Java反射工厂模式详解
18 0
|
7天前
|
Java
Java配置大揭秘:读取自定义配置文件的绝佳指南
Java配置大揭秘:读取自定义配置文件的绝佳指南
11 0
Java配置大揭秘:读取自定义配置文件的绝佳指南
|
7天前
|
监控 安全 Java
常见 Java 代码缺陷及规避方式(中)
常见 Java 代码缺陷及规避方式(中)
22 1
|
9天前
|
设计模式 算法 Java
23种设计模式,模板方法模式的概念优缺点以及JAVA代码举例
【4月更文挑战第10天】模板方法模式是一种行为设计模式,它定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些特定步骤。
13 0
|
10天前
|
设计模式 Java
23种设计模式,状态模式的概念优缺点以及JAVA代码举例
【4月更文挑战第9天】状态模式是一种行为设计模式,允许一个对象在其内部状态改变时改变它的行为,这个对象看起来似乎修改了它的类。
25 4
|
10天前
|
算法 安全 Java
java代码 实现AES_CMAC 算法测试
该代码实现了一个AES-CMAC算法的简单测试,使用Bouncy Castle作为安全提供者。静态变量K定义了固定密钥。`Aes_Cmac`函数接受密钥和消息,返回AES-CMAC生成的MAC值。在`main`方法中,程序对给定的消息进行AES-CMAC加密,然后模拟接收ECU的加密结果并进行比较。如果两者匹配,输出&quot;验证成功&quot;,否则输出&quot;验证失败&quot;。辅助方法包括将字节转为16进制字符串和将16进制字符串转为字节。
|
11天前
|
NoSQL Java Redis
Java自定义线程池的使用
Java自定义线程池的使用