1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
|
public class ProxyUtil {
static JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
public static <T> T getProxy(Object target, MyInvocationHandler handler, Class<T> ... interfaces) throws Exception { if(interfaces == null || interfaces.length==0){ System.out.println("该对象没有实现接口,无法代理!"); return null; } System.out.println("即将针对接口"+interfaces+"进行动态代理..."); StringBuffer java = new StringBuffer(); String proxyPackage = "com.sam.proxy"; java.append("package "+proxyPackage+";\n\n"); java.append(Arrays.stream(interfaces).map(c->"import "+c.getName()).collect(Collectors.joining(";\n"))+";\n"); java.append( "import "+target.getClass().getName()+";\n" + "import java.util.Arrays;\n" + "import "+MyInvocationHandler.class.getName()+";\n\n" + "// TODO 这个类是由ProxyUtil自动生成的\n"+ "public class MyProxyOf"+target.getClass().getSimpleName()+" implements "+ Arrays.stream(interfaces).map(Class::getSimpleName).collect(Collectors.joining(","))+" {\n" + " private "+target.getClass().getSimpleName()+" target;\n" + " private "+MyInvocationHandler.class.getSimpleName()+" handler;\n\n" + " public MyProxyOf"+target.getClass().getSimpleName()+"("+target.getClass().getSimpleName()+" target, "+MyInvocationHandler.class.getSimpleName()+" h){\n" + " this.target = target;\n" + " this.handler = h;\n" + " }\n"); for(Method method : target.getClass().getDeclaredMethods()){ java.append("\n\t@Override\n\tpublic "+method.getReturnType().getName()+" "+method.getName()+"(");
List<String> params = IntStream.range(0,method.getParameterTypes().length).mapToObj(i->method.getParameterTypes()[i].getName() +" var"+i).collect(Collectors.toList()); java.append(String.join(", ",params)); java.append(")"); if(method.getExceptionTypes().length > 0){ java.append("thorws "+ Arrays.stream(method.getExceptionTypes()).map(Class::getName).collect(Collectors.joining(", "))); } java.append("{\n"); java.append("\t\tSystem.out.println(\"代理对象中即将调用invoke.....\");\n"); java.append("\t\ttry{\n"); if(method.getParameterTypes().length == 0){ java.append("\t\t\t"+(method.getReturnType()==void.class?"":("return ("+method.getReturnType().getName()+")"))+"handler.invoke(this, target.getClass().getMethod(\""+method.getName()+"\"), target);\n"); }else{ List<String>vars = IntStream.range(0,method.getParameterTypes().length).mapToObj(i->"var"+i).collect(Collectors.toList()); List<String>paramClazz = Arrays.stream(method.getParameterTypes()).map(c->c.getName()+".class").collect(Collectors.toList()); java.append("\t\t\tClass[] paramClazz = new Class[]{"+String.join(",",paramClazz)+"};\n"); java.append("\t\t\t"+(method.getReturnType()==void.class?"":("return ("+method.getReturnType().getName()+")"))+"handler.invoke(this, target.getClass().getMethod(\""+method.getName()+"\", paramClazz), target, "+String.join(",",vars)+");\n"); }
java.append("\t\t}catch(Exception ex){\n"); if(method.getExceptionTypes().length > 0){ java.append("\t\tList<Class> methodExs = Arrays.asList("+ String.join(",",Arrays.stream(method.getExceptionTypes()).map(c->c.getName()+".class").collect(Collectors.toList()))+");\n"); java.append("\t\t\tif(methodExs.contains(ex.getClass())){throw ex;}\n"); } java.append("\t\t\tex.printStackTrace();\n"); if(method.getReturnType() != void.class){ java.append("\t\t\treturn null;\n"); } java.append("\t\t}\n"); java.append("\t}\n"); } java.append("}\n");
String filePath = System.getProperty("user.dir")+"/src/main/java/"+proxyPackage.replaceAll("\\.","/"); String fileprefix = "MyProxyOf"+target.getClass().getSimpleName(); File dir = new File(filePath); if(!dir.exists()){ dir.mkdirs(); } File javaFile = new File(filePath + "/" +fileprefix +".java"); if(javaFile.exists()){ javaFile.delete(); } FileWriter fw = new FileWriter(javaFile); fw.write(java.toString()); fw.flush(); fw.close(); boolean result = compilerJavaFile(filePath + "/" + fileprefix +".java",System.getProperty("user.dir")+"/target/classes/"); if(result){ Class tClass = Class.forName(proxyPackage+".MyProxyOf"+target.getClass().getSimpleName()); return (T) tClass.getConstructor(target.getClass(),MyInvocationHandler.class).newInstance(target,handler); } return null; }
public static boolean compilerJavaFile(String sourceFileInputPath, String classFileOutputPath) { System.out.println("sourceFileInputPath="+sourceFileInputPath); System.out.println("classFileOutputPath="+classFileOutputPath); try{ System.out.println("输出到:"+classFileOutputPath); Iterable<String> options = Arrays.asList("-d", classFileOutputPath); StandardJavaFileManager fileManager = javaCompiler.getStandardFileManager(null, null, null); Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(new File(sourceFileInputPath))); boolean flag = javaCompiler.getTask(null, fileManager, null, options, null, compilationUnits).call(); if(flag){ System.out.println("动态编译成功!"); } return flag; }catch (Exception ex){ ex.printStackTrace(); if(ex instanceof ClassNotFoundException){ System.out.println("动态编译失败!"); System.out.println("把JDK/lib/tools.jar加入到环境变量中"); }
return false; }
}
public static void main(String[] args) throws Exception{ UserService instance = getProxy(new UserServiceImpl(), (proxy,method,target,params)->{ System.out.println("在lambda中的增强代理.....");return method.invoke(target,params); }, UserService.class); System.out.println("-----------------开始运行"); instance.addUser(new User("wangwu",20)); } }
|