动态代理
动态代理
为什么需要代理
对象如果嫌身上干的事太多,可以通过代理来转移部分职责;对像有什么方法想被代理,代理就一定要有对应的方法。
入门案例
一个歌手能唱歌和跳舞,代理人为他代理相应的唱歌跳舞业务。
创建歌手类,会唱歌和跳舞:
public class BigSinger implements Singer{
private String name;
public Singer(name) {
this.name = name;
}
public String sing(String name) {
System.out.println(this.name + "正在唱:" + name);
return "谢谢";
}
public void dance(String name) {
System.out.println(this.name + "正在跳舞:");
}
}
创建接口表示该歌手要代理的业务
public interface Singer {
String sing(String name);
void dance();
}
创建代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyUtil {
public static Singer createProxy(BigSinger bigSinger){
/**
* newProxyInstance(ClassLoader loader,
* Class<?>[] interfaces,
* InvocationHandler h)
* 参数1: 用于制定一个类加载器
* 参数2:指定生成的代理长什么样子,也就是有哪些方法
* 参数3:用来指定生成的对象要干什么事情
*/
Singer singerProxy = (Singer) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
new Class[]{Singer.class}, new InvocationHandler() {
@Override // 回调方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 代理对象要做的事情,会在这里写代码
if(method.getName().equals("sing")){
System.out.println("准备话筒,收钱20万");
}else if(method.getName().equals("dances")){
System.out.println("准备场地,收钱1000万")
}
return method.invoke(bigSinger, args);
}
});
return singerProxy;
}
}
编写测试类
public class Test{
BigSinger s = new BigSinger("张学友");
Singer singerProxy = ProxyUtil.createProxy(s);
String rs = startProxy.sing("吻别");
System.out.println(rs);
}