JDK的动态代理
首先谈一下我自己的理解的JDK的动态代理,举个例子,刘德华要开演唱会,刘德华负责唱歌跳舞,刘德华的经纪人(张三),张三就去负责收钱,陪吃饭等等。
刘德华和张三是两个独立的对象,要想办这场演唱会,张三先去收钱,然后刘德华去唱歌跳舞,演出完毕,俩人一起吃个饭,把这两个独立的对象组装到一起,就是动态代理的过程。
下面上代码看一下
先定义一个明星接口,这里唱和跳
package com.ymy.starInterface;
public interface Star {
public void sing();
public void dance();
}
然后写明星接口的实现类 就是陈刀仔了
package com.ymy.starImpl;
import com.ymy.starInterface.Star;
public class LiuDeHua implements Star {
@Override
public void sing() {
System.out.println("刘德华唱歌");
}
@Override
public void dance() {
System.out.println("刘德华跳舞");
}
}
写经纪人的接口,会收钱和陪人吃饭
package com.ymy.economicInterface;
public interface EconomicMan {
public void collectMoney();
public void eat();
}
写经纪人的实现类,这里是张三
package com.ymy.economocImpl;
import com.ymy.economicInterface.EconomicMan;
public class ZhangSan implements EconomicMan {
@Override
public void collectMoney() {
System.out.println("收钱");
}
@Override
public void eat() {
System.out.println("陪刘德华吃饭");
}
}
到现在,很明显,刘德华和张三是两个独立的对象,办的事情也没有任何联系,那么如何先让张三收钱,刘德华演出,再一起吃饭?写一段测试程序。
package com.ymy.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.ymy.economicInterface.EconomicMan;
import com.ymy.economocImpl.ZhangSan;
import com.ymy.starImpl.LiuDeHua;
import com.ymy.starInterface.Star;
public class Test {
public static void main(String[] args) {
//目标 刘德华
Star liuDeHua = new LiuDeHua();
//经纪人 张三
EconomicMan zhangSan = new ZhangSan();
//代理对象 刘德华增强版
Star liuDeHuaProxy =
(Star)Proxy.newProxyInstance(
liuDeHua.getClass().getClassLoader(),
liuDeHua.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
zhangSan.collectMoney();
Object obj = method.invoke(liuDeHua, args);
zhangSan.eat();
return obj;
}
});
liuDeHuaProxy.sing();
System.out.println("------------");
liuDeHuaProxy.dance();
}
}
先来看一下测试结果
收钱,演出,吃饭,把两个人的功能组合到一起,可以理解是加强版的目标类。
那么要增强就要调用Proxy.newProxyInstance(loader, interfaces, h)方法。
第1个参数是目标类(LiuDeHua)的加载器可以用反射机制来完成。
第2个参数是目标类实现的接口,接口的方法可以被liuDeHuaProxy调用。
第3个参数是组合两个人的功能的过程,一般用匿名内部类实现,按照逻辑上的顺序就是张三先收钱,刘德华去演出,最后一起吃饭。