以下代码是我在下面这篇博客看到的,因为有些地方不理解,所以先按自己的方式背下来。
https://blog.csdn.net/briblue/article/details/73928350?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
代理模式其实就是为了增强现有的功能。下面是卖酒的动态代理的例子。
卖酒需要实现下面这个接口(类似于卖酒许可证)
package com.frank.test;
public interface SellWine {
void mainJiu();
}
卖茅台酒需要实现卖酒接口。可是下面卖茅台酒的功能过于简单,我们想使用代理模式对其增强。
public class MaotaiJiu implements SellWine {
@Override
public void mainJiu() {
// TODO Auto-generated method stub
System.out.println("我卖得是茅台酒。");
}
}
通过java内置的 Proxy 的静态方法 newProxyInstance 可以动态创
建代理。
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces, InvocationHandler h)
newProxyInstance方法包含三个参数:
ClassLoader:类加载器
它是用于加载代理对象字节码的。和被代理对象使用相同的类加载器(固定写法: 被代类.getClass().getClassLoader())。
Class[]:代码要用来代理的接口(固定写法: 被代理类.getClass().getInterfaces())。
InvocationHandler:用于提供增强的代码,它是一个接口。通过实现它内部的invoke方法对代理对象进行增强。
invoke方法有三个参数:
invoke(Object proxy, Method method, Object[] args
- proxy 代理对象的引用
- method 代理对象调用的方法
- args 调用的方法中的参数
我们不需要传上面三个参数,只要实现invoke方法的方法体就行了。
public class GuitaiA implements InvocationHandler {
private Object pingpai;
public GuitaiA(Object pingpai) {
this.pingpai = pingpai;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
System.out.println("销售开始 柜台是: "+this.getClass().getSimpleName());
method.invoke(pingpai, args);
System.out.println("销售结束");
return null;
}
}
上面代码主要就method.invoke(pingpai, args)这句难以理解。它的含义是对被代理对象pingpai的method方法传入参数args,它是原有方法在代理类中的体现形式。
测试
使用动态代理来代理茅台酒
InvocationHandler jingxiao1 = new GuitaiA(maotaijiu)构造方法会把maotaijiu传给柜台对象的Pingpai变量。dynamicProxy.mainJiu()调用卖酒方法,因为是代理茅台的卖酒,所以InvocationHandler中method方法就是mainjiu。method.invoke(pingpai, args)会执行pingpai为maotai的mainjiu方法。
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
MaotaiJiu maotaijiu = new MaotaiJiu();
InvocationHandler jingxiao1 = new GuitaiA(maotaijiu);
SellWine dynamicProxy = (SellWine) Proxy.newProxyInstance(MaotaiJiu.class.getClassLoader(),
MaotaiJiu.class.getInterfaces(), jingxiao1);
dynamicProxy.mainJiu();
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。