Java设计模式-代理模式

2018-12-14  本文已影响0人  爱情绅士

什么是代理模式

image.png

代理模式需要满足以下几点:

  1. 有两个对象:被代理人、代理人
    这里是小王和媒婆
  2. 这件事必须要做,但是自己没时间做或不愿意做,只得找代理
    小王单身必须找媳妇,但是工作忙没时间找,交给媒婆
  3. 被代理人必须知道代理人的全部信息
    媒婆必须知道小王的相亲要求

这三点相信很好理解,也会在我们的代码中出现

怎么实现动态代理

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.找媳妇();
    }
}

结果:

result.png
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.找媳妇();
    }
}

结果一样

什么是动态代理

你调用哪个方法,它就给你代理哪个方法 ,这叫动态
原理:
1 拿到被代理对象的引用,获取它的接口
2 由JDK 重新生成一个类,并且实现这个接口
3 根据这个拿到的引用,重新生成一个class字节码,然后编译

image.png
image.png

结语:实现动态代理有两个方法 jdk 和 cglib 。jdk 由于构造动态代理类需要接口,所以必须要有接口。cglib 只需要设置一下父类,自动生成一个类,继承被代理对象,把子类的引用指向父类。
以上是不同,相同之处是原理一样: 字节码重组

PS:为了更加易于理解,我取了中文名。虽然存在,但并不合理。
我自己写着也别扭,将就着看吧,以后会做到符合规范。

上一篇 下一篇

猜你喜欢

热点阅读