自定义Java类加载器的实现
来源:互联网 发布:windows网络上有重名 编辑:程序博客网 时间:2024/06/05 20:35
既然类加载器也不过是一个将需要的class文件加载在内存里的普通Java类,(具体参见上一篇博客) 那么我们是否可以通过编写实现自定义Java类加载器呢?答案是肯定的。
我们参照java.lang包下的ClassLoader来编写自定义加载器。
首先定义一个Student类,这里是通过对Student这个类生成的class文件加密(在项目的bin目录下)实现绕过系统的ApplicationClassLoader,而是靠自定义的加载器加载,类里没有定义方法(因为可能自己定义的加载器有问题,类无法加载,这样没办法调用该方法),而是重写toString方法,代码如下:
public class Student {public String toString(){ return "学习中"; }}然后开始新建一个类加载器MyClassLoader 继承自ClassLoader,这里直接定义main方法进行加密,在里面定义原来class文件所在路径,和加密后的class文件路径(我这里是在项目下新建一个文件夹test_lib,作为自己的class目录)代码如下:
public class MyClassLoder extends ClassLoader {public static void main(String[] args) {String srcPath="D:\\workbases\\java\\bin\\com\\huaxin\\classLoader\\Student.class"; String destPath="test_lib\\Studet.class"; //加密 encrypt(srcPath,destPath);} }接着编写加密算法(不是重点,所以写的很简单比较简单,也方便解密)构建文件输入流 ,在读的时候对其加一,代码如下:
//加密处理 破坏原class,使得ApplicationClassLoader无法加载 public static void encrypt(String srcPath,String destPath){try {InputStream in=new FileInputStream(srcPath);OutputStream out=new FileOutputStream(destPath);int i;while((i=in.read())!=-1){out.write(i+1);}in.close();out.close();} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}}然后运行项目,刷新可以看见在新建的文件夹test_lib下,有编译后生成的Student.class文件,
将这个文件复制拷贝到系统class文件的目录下,(就是上面的srcPath,将原来的Student.class覆盖掉)这时我们在新建一个Test类,让它去引入Student类,发现程序报错,可见系统的ApplicationClassLoader加载器已经没办法加载这个破坏后的class文件,需要使用自己的加载器进行解密,再加载,继续写自定义的加载器(注意,此时不要再动Student.java文件,不然系统很快重新编译,就无法达到使用自己的加载器的目的)
然后继续在类加载器MyClassLoader中定义解密算法
//解密处理public static void desencrypt(String srcPath,OutputStream out){try {InputStream in=new FileInputStream(srcPath);int i;while((i=in.read())!=-1){out.write(i-1); //还原}} catch (Exception e) {// TODO: handle exception}}
借鉴ClassLoader的API,我们知道自定义的加载器需要重写findClass方法,代码如下:
@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException{//检验是否触发 findClass,将name值传入System.out.println("name="+name);//拼接传入的路径值String srcPath="test_lib\\"+name;//将本地文件读到内存中 向内存中输出的流ByteArrayOutputStream baos=new ByteArrayOutputStream(); //读到内存后进行还原desencrypt(srcPath,baos);//得到Student.class在内存中的字节数组byte[] buf = baos.toByteArray();//将字节数组得到对应的Class实例return defineClass(buf,0,buf.length); //return super.findClass(name); }
然后我们在定义的Test文件中再次加载Student类,
public class Test {public static void main(String[] args) throws Exception {//创建自定义加载器对象(最终返回类的字节码)Class c=new MyClassLoder ().loadClass("Studet.class"); //直接实例化对象输出 调用toString方法System.out.println(c.newInstance().toString());}}
后台输出:
至此,使用自己的类加载器加载到了Student类
最后说一个尴尬的地方由于我在第一次加密时将保存路径destPath中的“student.class"错写成"Studet.class",解密的时候一直报类找不到异常,我还在纳闷,看了半天发现自己写错了,这真是瞎呀,为了警戒自己,也没有改,直接留下来了(其实我是懒得再截图什么的,O(∩_∩)O),经常犯这样低级的错误,下次要睁大眼睛了。
- 自定义Java类加载器的实现
- java 自定义类加载器ClassLoader的实现方式
- 实现java中自定义类加载器
- 自定义实现Java类加载器
- Java自定义类加载器实现
- 自定义类加载器的实现
- 自定义类加载器的实现,类加载过程
- 自定义类加载器的实现,类加载过程
- 自定义JAVA的类加载器
- Java自定义的类加载器
- Java自定义的类加载器
- Java 自定义类加载器实现插件式开发
- Java 自定义类加载器实现插件式开发
- Java虚拟机----自定义类加载器:实现对字节码的加密解密
- JAVA自定义类加载器
- Java自定义类加载器
- 【java】自定义类加载器
- java自定义类加载器
- iOS UILabel的行间距
- 1031. Hello World for U (20)
- WV.30-大数阶乘算法10-用Stirling逼近近似计算阶乘的探讨与应用
- JSON字符串转换成JSON对象
- WP开发入门指南:如何学习WP开发?
- 自定义Java类加载器的实现
- 1032. Sharing (25)
- Python语言计算1到10中偶数项的和
- DOM之下拉select复习
- 1033. To Fill or Not to Fill (25)
- Picasso扩展库
- 图集 html字段 文本颜色 错误
- 1034. Head of a Gang (30)
- Python 集合