1、手动创建handle接口
public interface InterfaceHandle { public Object invoke(Method method, Object[] args); }
2、实现handle接口
public class User_InvoctionHandle implements InterfaceHandle { private Object target; public User_InvoctionHandle(Object target) { this.target = target; } public Object invoke(Method method, Object[] args) { System.out.println("我是自定义invoke方法"); try { return method.invoke(this.target, null); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } }
3、手写代理类(附带逻辑重写)
public class ProxyUtil { public static Object getInstance(Class targetInfo, User_InvoctionHandle handle) { Object proxy = null; // Class targetInfo = target.getClass().getInterfaces()[0]; String tab = "\t"; String line = "\n"; String implName = targetInfo.getSimpleName(); //创建java内容 String javaContent = ""; //package String packageContent = "package com.proxy;" + line; //importClass String impPackageContent = "import "+handle.getClass().getName()+";"+line+ "import java.lang.reflect.Method;"+line+ "import "+targetInfo.getName()+";"+line; //创建类体 String classContent = "public class $Proxy implements " + implName + " {" + line; //创建私有对象handle String privateObject = tab + "private " + handle.getClass().getSimpleName() + " h;" + line; //创建构造,将handle当做对象 String constructorContent = tab + "public $Proxy (" + handle.getClass().getSimpleName() + " h ){" + line; constructorContent += tab + tab + "this.h = h;"; constructorContent += line + tab + "}" + line; //创建方法 String methedContent = ""; Method[] methods = targetInfo.getDeclaredMethods(); for (Method method : methods) { //获取方法的返回类型 String methodTypeName = method.getReturnType().getSimpleName(); //获取方法的名字 String methodName = method.getName(); methedContent += tab + "public " + methodTypeName + " " + methodName + " ("; //创建参数 Object[] args = method.getParameterTypes(); String argContent = ""; for (int i = 0; i < args.length - 1; i++) { //获取参数的类型 String argsTypeName = args[i].getClass().getSimpleName(); //获取参数名称 i1 i2 argContent = argsTypeName + " i" + i; if (i != args.length - 1) { //多个参数的情况下需要使用','但是最后一个不需要 argContent += ","; } } //组装方法内容,会自动将方法与目标方法一致 methedContent += argContent + "){" + line + tab + tab +"try{" + line + tab + tab + tab + "Method method = Class.forName(\""+targetInfo.getName()+"\").getDeclaredMethod(\""+method.getName()+"\");"+line + tab + tab + tab ; if(!"void".equals(methodTypeName)){ methedContent+= "return ("+methodTypeName+")"; } methedContent+= "h.invoke(method,null);" + line + tab + tab +"}catch(Exception e){" + line + tab + tab + tab + "e.printStackTrace();" + line + tab + tab +"}"; if(!"void".equals(methodTypeName)){ methedContent+= line + tab + tab +"return null;"; } methedContent+= line + tab +"}"+line+line; } javaContent = packageContent + impPackageContent + classContent + privateObject + constructorContent + methedContent + line + "}"; //1、使用IO字符流将创建好String 放到D盘中,用于查看是否存在问题。 String filePath = "D:\\com\\proxy\\"; String classFileName = "com.proxy.$Proxy"; File fileDir = new File("D:\\com\\proxy\\"); try { if (!fileDir.isDirectory()) { fileDir.mkdirs(); } File file = new File("D:\\com\\proxy\\$Proxy.java"); if (!file.exists()) { file.createNewFile(); } FileWriter fileWriter = new FileWriter(file); fileWriter.write(javaContent); fileWriter.flush(); fileWriter.close(); //创建java编译器 JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler(); //第三方管理器 StandardJavaFileManager fileMgr = javaCompiler.getStandardFileManager(null, null, null); //将java文件放到管理器中 Iterable units = fileMgr.getJavaFileObjects(file); //创建编译任务 JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileMgr, null, null, null, units); //开始启动任务 task.call(); fileMgr.close(); //使用反射获取编译后的$Proxy对象 URL [] urls = new URL[]{new URL("file:D:\\\\")}; URLClassLoader ucl = new URLClassLoader(urls); Class clazz = ucl.loadClass(classFileName); Constructor constructor = clazz.getConstructor(User_InvoctionHandle.class); proxy = constructor.newInstance(handle); System.out.println("成功!"); } catch (Exception e) { System.out.println("失败!"); e.printStackTrace(); } return proxy; } }
4、测试
public static void main(String args[]) { //调用手动写的代理 ObjectDao objectDao = (ObjectDao) ProxyUtil.getInstance(ObjectDao.class, new User_InvoctionHandle(new User_Defined_Dao())); System.out.println(objectDao.queryStr()); }
5、测试重生成的$Proxy代理类及class
自动生成代理类的编码
package com.dao; import com.handle.User_InvoctionHandle; import java.lang.reflect.Method; import com.dao.ObjectDao; public class $Proxy implements ObjectDao { private User_InvoctionHandle h; public $Proxy (User_InvoctionHandle h ){ this.h = h; } public void query (){ try{ Method method = Class.forName("com.dao.ObjectDao").getDeclaredMethod("query"); h.invoke(method,null); }catch(Exception e){ e.printStackTrace(); } } public String queryStr (){ try{ Method method = Class.forName("com.dao.ObjectDao").getDeclaredMethod("queryStr"); return (String)h.invoke(method,null); }catch(Exception e){ e.printStackTrace(); } return null; } }
结果