设计模式之Proxy

它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。


代理可以分静态代理和动态代理

两个场景简单的说明下两者:

静态代理:

例:霖哥是老板,有签字,开会的功能,公务繁忙,所以找了个小蜜,有什么事先经过小蜜,通过小蜜之后再到霖哥那,但是具体做的事情(比如签字,开会)还是霖哥做,这个小蜜就相当于是代理.

动态代理:

例:比如霖哥,亚淞还有山山要学外语,于是找到了一个外语辅导班,但是霖哥要学的是日语,亚淞要学英语,山山要学法语于是辅导班就给霖哥安排了一个日语老师(美女哦),给亚淞安排了一个英语老师(非洲来的猛汉,哈哈)给山山安排了一个法语老师(法国小鲜肉,男的).这时这个外语辅导班就相当于动态代理.

代码:

静态代理:

interface Subject{
    //定义抽象方法play()
    public String play (String name, int age);
}

class RealSubject implements Subject {
    public String play(String name, int age) {
        return "姓名: " + name + ",年龄:" + age;
    }
}

class ProxySubject implements Subject{
    private  Subject sub = null;
    public ProxySubject(Subject sub){
        this.sub = sub;
    }
    public String play(String name , int age){
        return this.sub.play(name,age);
    }
}

public class StaticProxyDemo {
    public  static void main(String args[]){
        Subject sub = new ProxySubject(new RealSubject());
        System.out.print(sub.play("汪庆邦",24));
    }
}

动态代理:

在java中要想实现动态代理机制,则需要java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类的支持

InvocationHandler接口的定义如下:

public interface InvocationHandler{

public Object invoke(Object proxy,Method method, Object[] args) throws Throwable

}

invoke()方法中的三个参数的意义依次是:被代理的对象、要调用的方法、方法调用时所需要饿参数。

 Proxy 类是专门完成代理的操作类,可以通过此类为一个或者多个接口动态的生成实现类。Proxy提供了如下的操作方法:

public static Object newProxyInstance(ClassLoader loader ,Class<?>[] interface, InvocationHandler h) throws IllegalArgumentException

通过newProxyInstance()方法可以动态的生成实现类。此方法中参数的意义依次为:

类加载器,得到全部的接口,得到InvocationHandler接口的子类实例。

先定义一个InvocationHandler接口的子类,以完成代理的具体操作。

public class MyInvocationHandler implements InvocationHandler
{
    private Object obj;//真实的主题
    public  Object bind(Object obj){//绑定真实操作主题
        this.obj = obj;
        //取得代理对象
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
    }
    //动态调用方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object temp = method.invoke(this.obj,args);
        return temp;
    }
}
在类的bind() 方法中接受被代理对象的真实主题实现,之后覆写InvocationHandler接口中的invoke ()  方法,完成具体的方法调用。

定义接口

interface Subject{
    //定义抽象方法play()
    public String play (String name, int age);
}

定义真实主题实现类

class RealSubject implements Subject {
    public String play(String name, int age) {
        return "姓名: " + name + ",年龄:" + age;
    }
}
以上定义了接口及真实主题类,这样在操作时直接将真实主题类的对象传入到MyInvocationHandler类的bind() 方法中MyInvocationHandler类的bind() 方法中即可。
public class DynaProxyDemo {
    public  static void main(String args[]){
        //实例化代理类操作
        MyInvocationHandle handler = new MyInvocationHandle();
        Subject sub = (Subject)handler.band(new RealSubject());// 绑定对象
        System.out.println(sub.play("汪庆邦",24));
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值