②、自定义类加载器MyClassLoader
package com.lc;import java.io.BufferedInputStream;import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.IOException;/** * 自定义ClassLoader * * @author liuchao * @date 2023/3/25 */public class MyClassLoader extends ClassLoader {/*** 负责加载的类所属目录*/public String classPath;/*** 包名*/public String packageName;public MyClassLoader(String packageName, String classPath) {this.packageName = packageName;this.classPath = classPath;}@Overrideprotected Class<?> findClass(String name) {//获取字节码完整路径String fileName = classPath + name + ".class";ByteArrayOutputStream baos = null;BufferedInputStream bis = null;try {//获取输入流bis = new BufferedInputStream(new FileInputStream(fileName));//获取输出流baos = new ByteArrayOutputStream();//读取数据写入输出流int len;byte[] data = https://www.isolves.com/it/cxkf/yy/JAVA/2023-06-07/new byte[1024];while ((len = bis.read(data)) != -1) {baos.write(data, 0, len);}//获取内存中完整的字节素组数据byte[] byteCodes = baos.toByteArray();//通过调用defineClass 方法将字节数组转换为class的实例return defineClass(packageName + "." + name, byteCodes, 0, byteCodes.length);} catch (IOException e) {throw new RuntimeException(e);} finally {try {if (null != baos) {baos.close();}if (null != bis) {bis.close();}} catch (IOException e) {throw new RuntimeException(e);}}}}
③、写测试代码MyClassLoaderTest
package com.lc;import java.lang.reflect.Method;/** * 测试 * * @author liuchao * @date 2023/3/25 */public class MyClassLoaderTest {public static void mAIn(String[] args) throws Exception {MyClassLoader classLoader = new MyClassLoader("com.lc", "/Users/liuchao/Desktop/");Class clazz = classLoader.loadClass("Demo");System.out.println("当前Demo类的加载器为:" + clazz.getClassLoader().getClass().getName());System.out.println("当前Demo类的加载器的父类加载器为:" + clazz.getClassLoader().getClass().getClassLoader().getClass().getName());Method method = clazz.getMethod("hello");Object obj = clazz.newInstance();method.setAccessible(Boolean.TRUE);method.invoke(obj);}}
【Java自定义类加载器全解】执行效果:
文章插图
至此我们的自定义类加载器就算完成了
6、自定义类加载器实现Java license我们改造第5节的代码
①、增加字节码加密方法
@Testpublic void test01() {//秘钥String secretKey = "12asdfwe23123212";String className = "Demo";//原字节码byte[] byteCodes = FileUtil.readBytes("/Users/liuchao/Desktop/" + className + ".class");//加密后的字节码byte[] encryptByteCodes = SecureUtil.aes(secretKey.getBytes()).encrypt(byteCodes);//加密后的字节码重新生成新的class文件放入 temp目录下FileUtil.writeBytes(encryptByteCodes, "/Users/liuchao/Desktop/temp/" + className + ".class");}
②、改造MyClassLoader类package com.lc;import cn.hutool.crypto.SecureUtil;import java.io.BufferedInputStream;import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.IOException;/** * 自定义ClassLoader * * @author liuchao * @date 2023/3/25 */public class MyClassLoader extends ClassLoader {/*** 负责加载的类所属目录*/public String classPath;/*** 包名*/public String packageName;/*** 秘钥*/public String secretKey;public MyClassLoader(String secretKey, String packageName, String classPath) {this.secretKey = secretKey;this.packageName = packageName;this.classPath = classPath;}@Overrideprotected Class<?> findClass(String name) {//获取字节码完整路径String fileName = classPath + name + ".class";ByteArrayOutputStream baos = null;BufferedInputStream bis = null;try {//获取输入流bis = new BufferedInputStream(new FileInputStream(fileName));//获取输出流baos = new ByteArrayOutputStream();//读取数据写入输出流int len;byte[] data = https://www.isolves.com/it/cxkf/yy/JAVA/2023-06-07/new byte[1024];while ((len = bis.read(data)) != -1) {baos.write(data, 0, len);}//获取内存中完整的字节素组数据 (加密的)byte[] encryptByteCodes = baos.toByteArray();//解密返回byte[] byteCodes = SecureUtil.aes(secretKey.getBytes()).decrypt(encryptByteCodes);//通过调用defineClass 方法将字节数组转换为class的实例return defineClass(packageName + "." + name, byteCodes, 0, byteCodes.length);} catch (IOException e) {throw new RuntimeException(e);} finally {try {if (null != baos) {baos.close();}if (null != bis) {bis.close();}} catch (IOException e) {throw new RuntimeException(e);}}}}
③、调用测试package com.lc;import java.lang.reflect.Method;/** * 测试 * * @author liuchao * @date 2023/3/25 */public class MyClassLoaderTest {public static void main(String[] args) throws Exception {String secretKey = "12asdfwe23123212";MyClassLoader classLoader = new MyClassLoader(secretKey, "com.lc", "/Users/liuchao/Desktop/temp/");Class clazz = classLoader.loadClass("Demo");System.out.println("当前Demo类的加载器为:" + clazz.getClassLoader().getClass().getName());System.out.println("当前Demo类的加载器的父类加载器为:" + clazz.getClassLoader().getClass().getClassLoader().getClass().getName());Method method = clazz.getMethod("hello");Object obj = clazz.newInstance();method.setAccessible(Boolean.TRUE);method.invoke(obj);}}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 类似老衲要还俗类型的小说
- |夏季野钓,2类钓位人比鱼多,遇上了赶紧抢
- excel分类汇总在哪里找
- excel分类汇总怎么使用
- excel分类汇总前应进行的操作包括
- excel分类筛选汇总
- excel如何分类筛选分类数据
- excel怎么筛选分类求和的公式
- excel如何做分类筛选
- excel怎么分类筛选同一姓名的人