模擬JDK定義一個InvokeHandlerjava
public interface MyInvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; }
定義一個實現類spring
package com.jv.own; import java.lang.reflect.Method; public class MyOwnInvocationHandler implements MyInvocationHandler{ private UserDao target; public MyOwnInvocationHandler(UserDao target){ this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("invoke before"); method.invoke(target,args); System.out.println("invoke after"); return null; } }
模擬JDK的Proxy類app
package com.jv.own; import javax.tools.JavaCompiler; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; import java.io.FileWriter; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; public class MyProxyUtil { private static final String l = "\n\r"; private static final String t = "\t"; public static Object newInstance(ClassLoader classLoader,Class[] interfaces,MyInvocationHandler handler) throws Exception{ StringBuilder sb = new StringBuilder(); StringBuilder sbImport = new StringBuilder(); StringBuilder sbImplements = new StringBuilder(); StringBuilder sbMethods = new StringBuilder(); //############################################生成源代碼############################################ //包定義 sb.append("package com.jv.own;").append(l+l); if(interfaces == null || interfaces.length==0){ throw new Exception("接口不能爲空"); } //生成導入和implements for (Class anInterface : interfaces) { sbImport.append("import "+anInterface.getName()+";"+l); sbImplements.append(anInterface.getSimpleName()+","); } sbImport.append("import java.lang.reflect.Method;").append(l+l); sbImport.append("import com.jv.own.MyInvocationHandler;").append(l+l); sb.append(sbImport.toString()); String temp = sbImplements.toString().substring(0,sbImplements.toString().lastIndexOf(",")); //類定義 sb.append("public class MyProxy implements ").append(temp).append("{").append(l).append(l); sb.append(t+"private MyInvocationHandler handler;").append(l); //構造函數 sb.append(t+"public MyProxy(").append("MyInvocationHandler handler){").append(l); sb.append(t+t+"this.handler = handler;").append(l).append(t).append("}").append(l).append(l); //生成接口裏面全部的 for (Class anInterface : interfaces) { Method[] methods = anInterface.getMethods(); for (Method method : methods) { String parameter = ""; String parameterType = ""; int i = 1; for(Class cl:method.getParameterTypes()){ parameter += cl.getName() + " p" + i++ +","; parameterType += "Class.forName(\""+cl.getTypeName()+"\")"+","; } if(parameter!=null&&!parameter.equals("")) { parameter = parameter.substring(0, parameter.lastIndexOf(",")); parameterType = parameterType.substring(0, parameterType.lastIndexOf(",")); } sbMethods.append(t).append("public ").append(method.getReturnType().getName()).append(" ").append(method.getName()) .append("(").append(parameter).append("){").append(l+t+t); sbMethods.append("try{").append(l+t+t+t); String args = "Object[] args = new Object[]{"; for(int j=1;j<i;j++){ args += "p"+j+","; } args = args.substring(0,args.lastIndexOf(","))+"};"; sbMethods.append(args).append(l+t+t+t); StringBuilder methodContent = new StringBuilder(); //methodContent.append("Method method = Class.forName(\""+anInterface.getTypeName()+"\").getMethod(\""+method.getName()+"\","+parameterType+");"); methodContent.append("Method method = "+anInterface.getName()+".class.getMethod(\""+method.getName()+"\","+parameterType+");"); sbMethods.append(methodContent.toString()).append(l+t+t+t); if(method.getReturnType().getName().equals("void")){ sbMethods.append("handler.invoke(this,method,args);").append(l+t+t); }else{ sbMethods.append("return "+"("+method.getReturnType().getName()+")"+"handler.invoke(this,method,args);").append(l+t+t); } sbMethods.append("}catch(Throwable e){"+l+t+t+t+"return null;"+l+t+t+"}"+l+t); sbMethods.append("}").append(l); } } sb.append(sbMethods.toString()); sb.append("}"); System.out.println(sb.toString()); //############################################將源代碼寫入磁盤文件############################################ String filePath = MyProxyUtil.class.getResource("").getPath() + "MyProxy.java"; System.out.println(filePath); FileWriter fileWriter = new FileWriter(filePath); fileWriter.write(sb.toString()); fileWriter.flush(); fileWriter.close(); //############################################編譯源代碼############################################ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); Iterable iterable = fileManager.getJavaFileObjects(filePath); JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, iterable); task.call(); fileManager.close(); //############################################將文件經過URLClassLocader或者自定義ClassLoader進行加載############################################ URL[] urls = new URL[]{new URL("file:f\\\\projects\\own\\spring-framework-master\\proxy\\out\\production\\classes")}; URLClassLoader urlClassLoader = new URLClassLoader(urls); Class clazz = urlClassLoader.loadClass("com.jv.own.MyProxy"); //############################################實例化############################################ //返回 Constructor[] constructors = clazz.getConstructors(); constructors[0].newInstance(handler); return constructors[0].newInstance(handler); } }
其餘類ide
package com.jv.own; public class User { private String userName; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } }
package com.jv.own; public interface UserDao { User query(String name); }
package com.jv.own; public class UserDaoImpl implements UserDao { @Override public User query(String name) { System.out.println("UserDaoImpl execute query"); return null; } }
測試類函數
package com.jv.own; public class TestMyProxy { public static void main(String[] args) { MyInvocationHandler handler = new MyOwnInvocationHandler(new UserDaoImpl()); try { UserDao dao = (UserDao)MyProxyUtil.newInstance(com.jv.jdk.UserDao.class.getClassLoader(),new Class[]{UserDao.class},handler); dao.query("a"); } catch (Exception e) { e.printStackTrace(); } } }
生成的代碼:測試
package com.jv.own; import com.jv.own.UserDao; import java.lang.reflect.Method; import com.jv.own.MyInvocationHandler; public class MyProxy implements UserDao{ private MyInvocationHandler handler; public MyProxy(MyInvocationHandler handler){ this.handler = handler; } public com.jv.own.User query(java.lang.String p1){ try{ Object[] args = new Object[]{p1}; Method method = com.jv.own.UserDao.class.getMethod("query",Class.forName("java.lang.String")); return (com.jv.own.User)handler.invoke(this,method,args); }catch(Throwable e){ return null; } } }
執行結果:ui