关于动态代理设计模式可以看以下博客:
http://blog.csdn.net/wangyongxia921/article/details/46124197
http://blog.csdn.net/wangyongxia921/article/details/46125379
以下是自己的理解:
代理为你实际的操作对象添加额外的操作,它作为一个中间对象,在任何时刻,当你想把“额外”的操作(比如跟踪日志,度量程序开销)和实际的对象分离开来,你都应该想到代理模式。
代理模式分为2种:
第一种是静态代理,缺点是需要提前创建好很多的代理类,造成代码累赘。
第二种是动态代理:它可以在运行时通过Proxy.newProxyInstance()动态的创建代理类,它将业务类和代理类解耦,只要客户端程序员实现InvovationHandler,可以随心所欲的形成自己的代理方式,而不是使用预先定义好的各种代理类(静态代理对不同接口会设置不同的代理类,这样我造成有很多很多的代理类,记忆和使用比较麻烦,我们让客户端程序员根据自己的业务需求来实现自己的代理类才是正道)在运行之前,都不需要真正的业务类,只有在运行时才需要真正的业务类,所以动态代理将我们的业务类和代理类的动态绑定延迟到运行时:
关键点:第一点是:Proxy.newProxyInstance(类加载器,类接口,我自己实现的Handler)
第二点是:InvocationHandler,里面有invoke()方法,调用方法的;
class MyHandler implements InvocationHandler
第三点,在invoke中的method,invoke()传递的对象应该是真正的业务对象,这一点要 注意。
public class Test {
public static void consumer(Work work){
work.doSome();
work.doElse();
}
public static void main(String[] args) {
//客户端
RealObject real = new RealObject();
Work work = (Work)(Proxy.newProxyInstance(RealObject.class.getClassLoader(), RealObject.class.getInterfaces(), new MyHandler(real)));
consumer(work);
}
}
interface Work{
public void doSome();
public void doElse();
}
//真正业务类
class RealObject implements Work{
@Override
public void doSome() {
System.out.println("Real Do some");
}
@Override
public void doElse() {
System.out.println("Real Do else");
}
}
class MyHandler implements InvocationHandler{
Object real;
public MyHandler(Object real) {
this.real = real;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName()=="doSome"){
System.out.println("Proxy Do some");
}//附加的操作
if(method.getName()=="doElse"){
System.out.println("Proxy Do else");
}//附加的操作
return method.invoke(real, args);
}
}
我们也可以创建一个代理类,直接实现InvocationHandler:
public class Proxy implements InvocationHandler {
private Object target;
/**
* 绑定委托对象并返回一个代理类
* @param target
* @return
*/
public Object GetInstance(Object target) {
this.target = target;
//取得代理对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
/**
* 调用方法
*/
public Object invoke(Object proxy, Method你甚至可以通过动态代理过滤某些方法,因为invoke中有Method参数,你也可以过滤某些参数因为有args。
method, Object[] args)
throws Throwable {
Object result=null;
System.out.println("before");
//执行方法
result=method.invoke(target, args);
System.out.println("after");
return result;
}