一、什么是动态代理?
无侵入式的给代码增加额外的功能。
对象有什么方法想被代理,代理就一定要有对应的方法。
定义接口,对象和代理都要去实现接口,在接口里面所有的方法就是想要被代理的方法。
二、代码实现
重要的一张图:
Star接口:
package mydynamicproxy;
public interface Star {
//可以把所有想要被代理的方法定义在接口中
public abstract String sing(String name);
//跳舞
public abstract void dance();
}
BigStar类:
package mydynamicproxy;
public class BigStar implements Star{
private String name;
public BigStar() {
}
public BigStar(String name) {
this.name = name;
}
//唱歌
@Override
public String sing(String name){
System.out.println(this.name+"正在唱"+name);
return "谢谢";
}
//跳舞
@Override
public void dance(){
System.out.println(this.name+"正在跳舞");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "BigStar{" +
"name='" + name + '\'' +
'}';
}
}
代理工具类ProxyUtil:
package mydynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//这个类的作用就是来创建一个代理
public class ProxyUtil {
//方法的作用就是给一个明星的对象来创建一个代理
//形参:被代理的明星对象
//返回值:给明星对象创建的代理
/*
需求:外面的人想要大明星去唱一首歌
1、获取代理的对象
代理对象 = ProxyUtil.createProxy(大明星的对象)
2、再调用代理的唱歌方法
代理对象.唱歌方法("泪桥");
*/
public static Star createProxy(BigStar bigStar){
Star star = (Star) Proxy.newProxyInstance(
ProxyUtil.class.getClassLoader(),//用于指定用那个类加载器,去加载生成的代理类
new Class[]{Star.class},//指定接口,这些接口用于指定生成的代理长什么样子,也就是有那些方法
//用于指定生成的代理对象要干什么事情。
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/*
* 参数一:代理的对象
* 参数二:要运行的方法sing(通过反射)
* 参数三:调用sing方法的时候,传递的实参
* */
if("sing".equals(method.getName())){
System.out.println("准备话筒");
System.out.println("收钱");
} else if ("dance".equals(method.getName())) {
System.out.println("准备场地");
System.out.println("收钱");
}
//代理 去找 大明星 开始 唱歌 或者 跳舞
//代码的表现形式:调用大明星里面 唱歌或者跳舞 的方法
return method.invoke(bigStar,args);
}
}
);
return star;
}
}
Test类:
package mydynamicproxy;
public class Test {
public static void main(String[] args) {
/*
需求:外面的人想要大明星去唱一首歌
1、获取代理的对象
代理对象 = ProxyUtil.createProxy(大明星的对象)
2、再调用代理的唱歌方法
代理对象.唱歌方法("泪桥");
*/
//1、获取代理的对象
BigStar bigStar = new BigStar("伍佰");
Star proxy = ProxyUtil.createProxy(bigStar); //方法的结果就是代理的对象
//2、调用唱歌的方法
String result = proxy.sing("泪桥");
System.out.println(result);
}
}
几个问题: