java自定义动态代理,代码创建->编译->载入
注:如ToolProvider.getSystemJavaCompiler() 返回 null则需JAVA_HOME由java\jdk改为Java\jre,同时将jdk\lib下将tools.jar复制到jre\lib下,改了JAVA_HOME后记得把path还是改成原来的,因为JAVA_HOME变了
HRProxySourceCreator.java
Test.java 测试类
package herui.core; import java.lang.reflect.Method; import herui.entity.A; import herui.entity.B; import herui.entity.C; public class Test { public static void main(String[] args) { HRProxy hrProxy = HRProxy.newProxyInstance(B.class.getInterfaces(), new HRInvocationHandler() { @Override public Object invoke(Object proxyObj, Method method, Object[] args) { System.out.println("调用:"+method.getName()); System.out.println("参数:"); for(int i=0; i< args.length;++i) { System.out.print(args[i]+","); } try { System.out.println("\n返回结果:"); return method.invoke(proxyObj, args); } catch (Exception e) { e.printStackTrace(); } return null; } }); B b = new B(); A a = hrProxy.getProxyObject(A.class, b); System.out.println(a.add(3, 5)); System.out.println(a.sub(13, 1)); a.print("自定义动态代理"); C c = new C(); A a2 = hrProxy.getProxyObject(A.class, c); System.out.println(a2.add(3, 5)); System.out.println(a2.sub(13, 1)); a2.print("自定义动态代理"); } }
HRProxySourceCreator.java 代理类构建
package herui.core; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Method; public class HRProxySourceCreator{ final static String BR = "\r\n"; final static String TB = "\t"; final static String SP = " "; final static String CA = ","; final static String SN = ";"; public static File create(Class<?>[] interfaces, HRInvocationHandler h) throws IOException { StringBuilder sBuilder = new StringBuilder(); addPackage(sBuilder, interfaces); String className = addClassHead(sBuilder, interfaces); addClassBody(sBuilder, interfaces, className); System.out.println(sBuilder.toString()); String path = HRProxySourceCreator.class.getResource("").getPath() + className+".java"; File file = new File(path); FileOutputStream fos = new FileOutputStream(file); fos.write(sBuilder.toString().getBytes()); fos.flush(); fos.close(); return file; } private static void addClassBody(StringBuilder sBuilder, Class<?>[] interfaces, String className) { sBuilder.append("{").append(BR) .append(TB).append("HRInvocationHandler h;").append(BR) .append(TB).append("Object tag;").append(BR) .append(TB).append("public ").append(className).append(" (").append("HRInvocationHandler h, Object tag) {").append(BR) .append(TB).append(TB).append("this.h = h;").append(BR) .append(TB).append(TB).append("this.tag = tag;").append(BR).append(TB).append("}"); for(int i=0; i<interfaces.length; ++i) { Method[] methods = interfaces[i].getMethods(); for(int j=0; j<methods.length; ++j) { addMethod(sBuilder, methods[j], interfaces[i].getName(), j); } } sBuilder.append(BR).append("}").append(BR); } private static void addMethod(StringBuilder sBuilder, Method method, String className, int index) { sBuilder.append(BR).append(BR).append(TB).append("public ").append(method.getReturnType().getName()) .append(SP).append(method.getName()).append(SP) .append("("); Class<?>[] types = method.getParameterTypes(); for (int i = 0; i < types.length; i++) { sBuilder.append(types[i].getTypeName()).append(SP).append("arg"+i).append(CA).append(SP); } sBuilder.delete(sBuilder.length()-2, sBuilder.length()-1); sBuilder.append(")").append(SP) .append("{").append(BR).append(TB).append(TB).append("Method method = ").append(className) .append(".class.getMethods()[").append(index).append("]").append(SN).append(BR); sBuilder.append(TB).append(TB).append("Object[] args = {"); for (int i = 0; i < types.length; i++) { sBuilder.append("arg"+i).append(CA).append(SP); } sBuilder.delete(sBuilder.length()-2, sBuilder.length()-1) .append("}").append(SN).append(BR).append(TB).append(TB); if(!"void".equals(method.getReturnType().getName())) { sBuilder.append("return (").append(method.getReturnType().getName()).append(")"); } sBuilder.append("h.invoke(tag, method, args)").append(SN).append(BR) .append(TB).append("}").append(BR); } private static String addClassHead(StringBuilder sBuilder, Class<?>[] interfaces) { sBuilder.append("public class "); String className = "$"; for(int i=0; i<interfaces.length; ++i) { className += interfaces[i].getSimpleName(); } sBuilder.append(className); sBuilder.append(" implements "); for(int i=0; i<interfaces.length; ++i) { sBuilder.append(interfaces[i].getName()).append(CA); } sBuilder.deleteCharAt(sBuilder.length()-1); sBuilder.append(SP); return className; } private static void addPackage(StringBuilder sBuilder, Class<?>[] interfaces) { sBuilder.append("package herui.core;").append(BR); sBuilder.append("import java.lang.reflect.Method;"); sBuilder.append(BR).append(BR); } }
HRProxy.java 代理类编译载入jvm,门面
package herui.core; import java.io.File; import java.lang.reflect.Constructor; import javax.tools.JavaCompiler; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; public class HRProxy { private HRInvocationHandler h; private Class proxyClass; private HRProxy() { throw new RuntimeException("no new instance by the construtor"); } private HRProxy(Class<?>[] interfaces, HRInvocationHandler h) { if(interfaces == null || h == null) { throw new RuntimeException("input invalid parameter"); } this.h = h; try { File file = HRProxySourceCreator.create(interfaces, h); //把生成的.java文件编译成.class文件 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager manage = compiler.getStandardFileManager(null, null, null); Iterable iterable = manage.getJavaFileObjects(file); JavaCompiler.CompilationTask task = compiler.getTask(null, manage, null, null, null, iterable); task.call(); manage.close(); // 编译生成的.class文件加载到JVM中来 HRClassLoader loader = new HRClassLoader(); proxyClass = loader.loadClass(file.getName().replace(".java", "")); file.delete(); } catch (Exception e) { e.printStackTrace(); } } public <T> T getProxyObject(Class<T> clzz, Object obj) { Constructor constructor = null; try { constructor = proxyClass.getConstructor(new Class[] {HRInvocationHandler.class, Object.class}); return (T) constructor.newInstance(h, obj); } catch (Exception e) { e.printStackTrace(); } return null; } public static HRProxy newProxyInstance(Class<?>[] interfaces, HRInvocationHandler h) { return new HRProxy(interfaces, h); } }
HRClassLoader.java 自定义类加载器
package herui.core; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class HRClassLoader extends ClassLoader{ private File classPathFile; public HRClassLoader(){ String classPath = HRClassLoader.class.getResource("").getPath(); this.classPathFile = new File(classPath); } @Override public Class<?> findClass(String name) throws ClassNotFoundException { String className = HRClassLoader.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(null != in){ try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if(out != null){ try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } } return null; } }
HRInvocationHandler.java 处理器接口
package herui.core; import java.lang.reflect.Method; public interface HRInvocationHandler { Object invoke(Object proxyObj, Method method, Object[] args); }
A.java 接口
package herui.entity; public interface A { Integer add(int a, int b); int sub(int a, int b); String print(String s); }
B.java 实现类1
package herui.entity; public class B implements A{ @Override public Integer add(int a, int b) { return a+b; } @Override public int sub(int a, int b) { return a-b; } @Override public String print(String s) { if(s == null) { s = ""; } System.out.printf(s); return s; } }
C.java 实现类2
package herui.entity; public class C implements A { @Override public Integer add(int a, int b) { return a+b+1000; } @Override public int sub(int a, int b) { return a-b-1000; } @Override public String print(String s) { if(s != null) { StringBuilder sBuilder = new StringBuilder(s); s = sBuilder.reverse().toString(); } System.out.println(s); return s; } }
示例结果:
本文主要展示一些原理,细节并未关注