使用Java的Proxy保护代理

代理模式:简单讲实现就是代理者和被代理者都实现了同一个接口,代理者内部一般有被代理的对象得引用来实现代理功能,客户调用的时候是对接口的引用,所以客户不在意他引用的是原本的对象还是代理者,只要实现接口它就能识别并调用方法。

在学设计模式时,保护代理举了Java内置的Proxy的例子,说实话,我看到头昏了 (+﹏+)~。
怎么说呢,好像理解了保护模式,却在例子里找不到匹配的类和接口。
看着类图和代码好久,才发现了关键的地方。
保护模式的类图:


这里说的实现了Subject接口的代理对象Proxy和java本身的Proxy完全是两个不同的对象。
应该是我们调用的Proxy代理对象是由java内置的Proxy生成的。
Proxy本身不是代理类,它的作用是生成满足条件的代理对象。
Proxy本身的静态方法:
public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
返回的才是代理对象。

这里我引用下别人的代码:
//代理和被代理对象都实现的接口
interface SellFisher {
    int sellFish();
}

//被代理对象,实现了SellFisher接口
public class ConcreteSellFisher implements SellFisher {

    public int sellFish() {
         System.out.println("my fish is delicious!!");
         return 10;
    }

}



//实现了InvocationHandler接口的对象,用在生成代理对象是的参数
public class ProxySellFisher implements InvocationHandler {

    private SellFisher sell;
    public ProxySellFisher(SellFisher sell) {
        this.sell = sell;
    }
    public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
        System.out.println("the fish price higher");
        return (Integer)method.invoke(sell, args)+10;
	/*这里是筛选的过程,一般是用method.getName()获取到调用到的方法名,和对应的方法比较后判断处理方式再将method.invoke()方法的返回值返回,第二个参数args是代理调用方法时传入的参数,这里还可以对参数进行修改。*/
    }

}


public class ClientTest {
    public static void main(String args[]) {
        SellFisher s = new ConcreteSellFisher();
        InvocationHandler p = new ProxySellFisher(s);
        Object obj = Proxy.newProxyInstance(s.getClass().getClassLoader(), s.getClass().getInterfaces(), p);
/*这里调用Proxy的静态方法newProxyInstance(),返回了真正用到的代理对象*/
        ((SellFisher)obj).sellFish();
    }
}




在代码中:
Proxy.newProxyInstance(s.getClass().getClassLoader(), s.getClass().getInterfaces(), p);
第一个参数被代理对象的类加载器
第二个参数是被代理对象实现的接口数组
第三个参数是实现了InvocationHandler的对象,它的作用是筛选。

这里补充点知识:Java有个Class对象,Class的实例表示在运行中的Java应用程序的类或者接口,就比如说类A,A.getClass()就得到A的Class对象,通过类加载器ClassLoader就能实例化A对象,这是在单件模式下,既私有构造方法的情况下能得到类对象的方法之一。

至于InvocationHandler接口,我现在也只知道它是配合Proxy创建代理的时候用到,让Proxy生成的代理按照invoke方法去过滤代理方法的调用。

讲到这里难点应该都能知道了,其它的简单看下代码应该都能理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值