public static Object newProxyInstance3(Class infc, InvocationHandler handler) throws Exception{
String rt = "\r\n";
String methodStr = "";
Method[] methods = infc.getMethods();
for(Method m : methods){
methodStr += " @Override " + rt +
" public void " + m.getName() + "()" + "{" + rt +
" try {" + rt +
" Method md = " + infc.getName() + ".class.getMethod(\"" + m.getName() + "\"); "+ rt +
" h.invock(this, md);" + rt + ""+
" } catch(Exception e){e.printStackTrace();}" + rt +
" }" + rt +
"}";
System.out.println("methodStr === " + methodStr);
}
String str =
"package com.inspur.simpleProxy;" + rt +
"import java.lang.reflect.Method;" + rt +
"public class TankTimeProxy implements " + infc.getName() + "{" + rt +
" com.inspur.simpleProxy.InvocationHandler h;" + rt +
" public TankTimeProxy(InvocationHandler handler){" + rt +
" this.h = handler;" + rt +
" }" + rt +
methodStr;
/*
* 要生成的目的地
*/
String fileName = System.getProperty("user.dir") + "/src/com/inspur/simpleProxy/TankTimeProxy.java";
File file = new File(fileName);
FileWriter fileWriter = new FileWriter(file);
fileWriter.write(str);
fileWriter.flush();
fileWriter.close();
/*
* 编译,生成 .class 文件
*/
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
System.out.println(compiler.getClass().getName());
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
Iterable iterable = fileManager.getJavaFileObjects(fileName);
CompilationTask task = compiler.getTask(null, fileManager, null, null, null, iterable);
task.call();
fileManager.close();
/*
* load to memory , create an instance
* 加载到内存,生成新对象
*/
// 将硬盘上的 Java 文件,放到内存中的类中,需要指定路径
// 此方式还可以从网上去 load 类,通过网络传来的类 , 也可以通过此方式来 load 类
// user.dir 当前文件根目录
URL[] urls = new URL[]{new URL("file:/" + System.getProperty("user.dir") + "/src")};
URLClassLoader urlClassLoader = new URLClassLoader(urls);
Class c = urlClassLoader.loadClass("com.inspur.simpleProxy.TankTimeProxy");
System.out.println(c);
// 拿到其中的构造方法,得到方法,通过参数来确定。 找一个构造方法,这个构造方法的参数类型是 Moveable ,便得到了 TankTimeProxy
Constructor constructor = c.getConstructor(InvocationHandler.class);
//Object m = constructor.newInstance(new Tank());
//m.move();
// c.newInstance(); 会产生一个新的构造方法
// Moveable m = (Moveable) constructor.newInstance(new Tank());
// return m;
// 因为我们并不知道 infc 实现的是哪个接口,将新生成的对象作为 Object 类型的返回值 返回回去
Object m = constructor.newInstance(handler);
return m;
}
Class clazz = Proxy.getProxyClass(classLoader,new Class[]{...});
Constructor constructor = clazz.getConstructor(
new Class[]{InvocationHandler.class});
Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));
Object result=method.invoke( proxied,args );
通过 java.lang.reflect 包下的方法实现动态代理
1、编写接口
2、编写委托类
3、编写处理类,实现 InvocationHandler 接口,实现记录的功能
4、编写 Client 类
上面的 Proxy 类是对类 $Proxy0 类的模拟,此类完成的功能是:
-- 动态生成代理对象
-- 将代理对象进行编译,得到 .class 文件,即 代理对象.class
-- 加载到内存
-- 通过构造方法,得到要调用的对应的方法
(以上是个人理解,自觉无法言明,在网上搜罗信息时发现此博主的文章甚是有理,请大家查看下一篇文章 -- 动态代理深入分析(一)(二))