动态代理,就是一个类首先是接口或者抽象类,这个类被具体类实现,我们想生成该类的代理,在产生代理的时候,可以在产生的过中动态的增加业务逻辑。
我们使用JDK自带的InvocationHandler 和Proxy类来实现动态代理。
如果被代理的类没有实现接口,我们使用cglib 直接生成二进制的代码。
Spring的AOP就是使用的这个接口来实现的面向切面编程。
以下是一个例子,在正常的业务前面,增加一个日志。
package dynamicAgent;
public interface Subject {
abstract public void request();
}
package dynamicAgent;
public class RealSubject implements Subject{
public void request() {
System.out.println("我是被代理对象");
}
}
package dynamicAgent;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicSubject implements InvocationHandler{
private Object obj;
public void setObj(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Log.log();
method.invoke(obj, args);
return null;
}
}
package dynamicAgent;
public class Log {
public static void log(){
System.out.println("我正在记录日志");
}
}
package dynamicAgent;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicSubject implements InvocationHandler{
private Object obj;
public void setObj(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Log.log();
method.invoke(obj, args);
return null;
}
}
package dynamicAgent;
import java.lang.reflect.Proxy;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
Subject sub=new RealSubject();
DynamicSubject ih=new DynamicSubject();
ih.setObj(sub);
Subject proxy=(Subject) Proxy.newProxyInstance(sub.getClass().getClassLoader(), sub.getClass().getInterfaces(),ih );
System.out.println(sub);
System.out.println(proxy);
proxy.request();
}
}