@Override
public void move() {
long start = System.currentTimeMillis();
System.out.println("1start");
try {
Thread.sleep((long) (Math.random()*1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("1end");
}
}
------> 这是要被代理类
package dynamic;
public class Tank1 extends Tank {
@Override
public void move() {
System.out.println("2start");
super.move();
System.out.println("2end");
}
}
----->这是继承被代理类
package dynamic;
public interface Interface {
void move();
}
------>含有move()方法的接口
package dynamic;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class DynamicProxy {
private static String newline = "\r\n";
private static String catalog = "E:/Stacticlei.java";
private static String catalog1 = "file:/E:/";
public static Object proxy(Class itf,dynamicInvoke d) throws Exception {
String methodName = "";
String methodStr = "";
String pakegeName = d.getClass().getName();
Method [] md = itf.getMethods();
for(Method m:md){
methodName=m.getName();
methodStr+= " @Override"+newline+
" public void "+methodName+"(){"+newline+
" try{"+newline+
" Method md ="+itf.getName()+".class.getMethod(\""+m.getName()+"\");"+newline+
" d.invoke(this,md);"+newline+
" }catch(Exception e){e.printStackTrace();}"+newline+
"}";
}
String str =
"import java.lang.reflect.Method;"+newline+
"import dynamic.dynamicInvoke;"+newline+
"public class Stacticlei implements "+ itf.getName()+"{"+newline+
" private dynamicInvoke d;"+newline+
" public Stacticlei(dynamicInvoke d){"+newline+
" this.d = d;"+newline+
" }"+newline+
//" private "+pakegeName+ " d;"
//+newline+
methodStr+"}";
File file = new File(catalog);
FileWriter fw = new FileWriter(file);
fw.write(str);
fw.flush();
fw.close();
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(
null, null, null);
Iterable compilationUnits = fileManager.getJavaFileObjects(catalog);
CompilationTask task= compiler.getTask(null, fileManager, null, null, null, compilationUnits);
// 编译源程序
boolean success = task.call();
fileManager.close();
//System.out.println((success)?"编译成功":"编译失败");
//class加载到内存
URL[] urls=new URL[]{new URL("file:/e:/")};
URLClassLoader classload=new URLClassLoader(urls);
Class clazz=classload.loadClass("Stacticlei");
Constructor c = clazz.getDeclaredConstructor(dynamicInvoke.class);
//c.setAccessible(true);
// Object o = c.newInstance(t);
//Method method=clazz.getMethod("move");
//method.invoke(o);
return c.newInstance(d);
}
}
--->生成java文件->编译成class->road到内存,返回对象
package dynamic;
import java.lang.reflect.Method;
public interface dynamicInvoke {
void invoke(Object o,Method m);
}
--->统一代理内容的接口
package dynamic;
import java.lang.reflect.Method;
public class DynamicTest implements dynamicInvoke{
private Object o;
public DynamicTest(Object o){
this.o=o;
}
@Override
public void invoke(Object obj, Method m) {
System.out.println("3start");
try {
m.invoke(o,new Object[]{});
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("3end");
}
}
-->实现了代理内容接口的代理类1
package dynamic;
import java.lang.reflect.Method;
public class rank implements dynamicInvoke{
private Object o;
public rank(Object o){
this.o=o;
}
@Override
public void invoke(Object obj, Method m) {
System.out.println("开始排位");
try {
m.invoke(o,new Object[]{});
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("排位结束");
}
}
-->实现了代理内容接口的代理类2
package dynamic;
public class Test2 {
public static void main(String[] args) throws Exception {
Tank t = new Tank1();
Interface itf = (Interface) DynamicProxy.proxy(Interface.class, new DynamicTest(t));
Interface itf2 = (Interface) DynamicProxy.proxy(Interface.class, new rank(itf));
itf2.move();
}
}
-->main 执行结果.
以上为jdk动态代理,cglib/asm 是直接生成二进制文件进行动态代理.原理相同
为什么要代理?解耦.为什么不用静态代理?解耦的前提下,类爆炸. |-| --》H诠释了AOP