什么是代理模式
image.png代理模式需要满足以下几点:
- 有两个对象:被代理人、代理人
这里是小王和媒婆 - 这件事必须要做,但是自己没时间做或不愿意做,只得找代理
小王单身必须找媳妇,但是工作忙没时间找,交给媒婆 - 被代理人必须知道代理人的全部信息
媒婆必须知道小王的相亲要求
这三点相信很好理解,也会在我们的代码中出现
怎么实现动态代理
1. JDK
public interface 男人 {
void 找媳妇();
}
public class 小王 implements 男人{
@Override
public void 找媳妇() {
System.out.println("我是小王");
System.out.println("今年28,要找一个白富美");
}
}
public class 媒婆 implements InvocationHandler {
//得到被代理人的信息,把被代理人的信息作为成员变量保存
private 男人 target;
//这个方法返回一个由JDK帮我们生成的一个代理类
//参数:哪个要被代理(找媳妇)就传进来
public Object getInstance(男人 target) {
//更新成员变量的信息,让我们知道是这个人找媳妇
this.target=target;
//利用java反射机制,让我们拿到这个类
Class clazz=target.getClass();
//JDK帮我们生成一个动态代理类,需要
// 1.传入要被代理的类 2.这个被代理类的接口 3.代理类是谁,this 就是指这个媒婆
return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我是媒婆,开始挑选对象");
System.out.println("下面是男方的要求");
//这个方法让我们去调用被代理人的方法
method.invoke(this.target,args);
System.out.println("媒婆:符合要求的配对");
return null;
}
}
public class Test {
public static void main(String[] args) {
男人 man= (男人) new 媒婆().getInstance(new 小王());
man.找媳妇();
}
}
结果:
2. CGlib
public class 小王{
public void 找媳妇() {
System.out.println("我是小王");
System.out.println("今年28,要找一个白富美");
}
}
public class 媒婆 implements MethodInterceptor {
public Object getInstance(Class clazz) {
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("我是媒婆,开始挑选对象");
System.out.println("下面是男方的要求");
//这个方法让我们去调用被代理人的方法
methodProxy.invokeSuper(o,objects);
System.out.println("媒婆:符合要求的配对");
return null;
}
}
public class Test {
public static void main(String[] args) {
小王 xw = (小王) new 媒婆().getInstance(小王.class);
xw.找媳妇();
}
}
结果一样
什么是动态代理
image.png你调用哪个方法,它就给你代理哪个方法 ,这叫动态
原理:
1 拿到被代理对象的引用,获取它的接口
2 由JDK 重新生成一个类,并且实现这个接口
3 根据这个拿到的引用,重新生成一个class字节码,然后编译
image.png
结语:实现动态代理有两个方法 jdk 和 cglib 。jdk 由于构造动态代理类需要接口,所以必须要有接口。cglib 只需要设置一下父类,自动生成一个类,继承被代理对象,把子类的引用指向父类。
以上是不同,相同之处是原理一样: 字节码重组
PS:为了更加易于理解,我取了中文名。虽然存在,但并不合理。
我自己写着也别扭,将就着看吧,以后会做到符合规范。
网友评论