public interface MyExtInvocationHandler { /** * 纯手写模拟 jdk动态模拟 InvocationHandler接口 * * @param proxy * @param method * @param args * @return * @throws Throwable */ public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException; } public class JavaClassLoader extends ClassLoader {
private File classPathFile;
public JavaClassLoader(){ // String classPath=JavaClassLoader.class.getResource("").getPath(); String classPath="D:\\code"; this.classPathFile=new File(classPath); }
@Override public Class<?> findClass(String name) throws ClassNotFoundException { String className= JavaClassLoader.class.getPackage().getName()+"."+name; if(classPathFile!=null){ File classFile=new File(classPathFile,name.replaceAll("\\.","/")+".class"); if(classFile.exists()){ FileInputStream in=null; ByteArrayOutputStream out=null; try { in=new FileInputStream(classFile); out=new ByteArrayOutputStream(); byte[] buff=new byte[1024]; int len; while ((len=in.read(buff))!=-1){ out.write(buff,0,len); } return defineClass(className,out.toByteArray(),0,out.size()); }catch (Exception e){ e.printStackTrace(); }finally { if(in!=null){ try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if(out!=null){ try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } } return null; } } public class ExtJdkInvocationHandler implements MyExtInvocationHandler { /** * 目标执行对象 (被代理的对象) */ private Object target;
public ExtJdkInvocationHandler(Object target) { this.target = target; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException { System.out.println("纯手写JDK动态代理日志拦截开始>>>>>"); Object result = method.invoke(target, args);// 执行代理对象的方法 System.out.println("纯手写JDK动态代理日志拦截结束>>>>>"); return result; }
// /** // * 获取代理对象 // * // * @param <T> // * @return // */ public <T> T getProxy() { return (T) MyProxy.newProxyInstance(new JavaClassLoader(), OrderService.class, this); } } public class MyProxy { static String rt = "\r\t";
/** * @param classInfo 被代理实现的接口信息 <br> * @param h * @return */ public static Object newProxyInstance(JavaClassLoader javaClassLoader, Class classInfo, MyExtInvocationHandler h) { try { // 1.创建代理类java源码文件,写入到硬盘中.. Method[] methods = classInfo.getMethods(); String proxyClass = "package com.cx.ext.jdk.proxy;" + rt + "import java.lang.reflect.Method;" + rt + "import com.cx.ext.jdk.proxy.MyExtInvocationHandler;" + rt + "public class $Proxy0 implements " + classInfo.getName() + "{" + rt + "MyExtInvocationHandler h;" + rt + "public $Proxy0(MyExtInvocationHandler h)" + "{" + rt + "this.h= h;" + rt + "}" + getMethodString(methods, classInfo) + rt + "}"; // 2. 将代理类源码文件写入硬盘中 String filename = "d:/code/$Proxy0.java"; File f = new File(filename); FileWriter fw = new FileWriter(f); fw.write(proxyClass); fw.flush(); fw.close();
// 3.使用JavaJavaCompiler 编译该$Proxy0源代码 获取class文件 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null); Iterable units = fileMgr.getJavaFileObjects(filename); JavaCompiler.CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units); t.call(); fileMgr.close();
//4.使用classClassLoader 将$Proxy0.class读取到内存中... Class proxy0Class = javaClassLoader.findClass("$Proxy0"); //5.使用java反射机制给函数中赋值 Constructor m = proxy0Class.getConstructor(MyExtInvocationHandler.class); Object o = m.newInstance(h); return o; } catch (Exception e) { e.printStackTrace(); ; } return null; }
public static String getMethodString(Method[] methods, Class intf) { String proxyMe = ""; for (Method method : methods) { proxyMe += "public void " + method.getName() + "() throws Throwable {" + rt + "Method md= " + intf.getName() + ".class.getMethod(\"" + method.getName() + "\",new Class[]{});" + rt + "this.h.invoke(this,md,null);" + rt + "}" + rt;
} return proxyMe; } } |