Java代理设计模式

1.代理设计模式
代理是基本的设计模式之一,它是开发者为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象。这些操作通常涉及与"实际“对象的通信,因此,代理通常充当着中间人的角色。
说的简单明了一些,你想买包零食,但是自己不想去超市,所以你把钱交给你的女朋友,你的女朋友拿着钱,替你去超市,给你买了零食(当然,后续她会买什么就不知道了)。你的女朋友就充当了这个代理的角色。你可以把下面的SimpleProxy想象为女朋友的角色。

interface Interface {
    void doSomething();

    void somethingElse(String str);
}
class RealObject implements Interface{
    //被代理对象
    @Override
    public void doSomething() {
        System.out.println("Do something");
    }

    @Override
    public void somethingElse(String str) {
        System.out.println("Something else " + str);
    }
}

class SimpleProxy implements Interface{
    //代理人
    private Interface proxied;  //被代理对象
    public SimpleProxy(Interface proxied){
        this.proxied = proxied;
    }
    @Override
    public void doSomething() {
        System.out.println("SimpleProxy do something");
        proxied.doSomething();
    }

    @Override
    public void somethingElse(String str) {
        System.out.println("SimpleProxy something else " + str);
        proxied.somethingElse(str);
    }
}

public class SimpleProxyDemo {

    public static void consumer(Interface iface){
        iface.doSomething();
        iface.somethingElse("BOBODA");
    }

    public static void main(String[] args) {
        consumer(new RealObject());
        consumer(new SimpleProxy(new RealObject()));
    }
}

因为consumer()接收的Interface,所以它无法知道正在获取的到底是RealObject还是SimpleProxy,因为这二者都实现了Interface。但是SimpleProxy已经被插入到了客户端和RealObject之间(你女朋友被你扔到了超市和你家的路上),因此它会执行操作,然后调用RealObject上相同的方法。
在任何时刻,只要你想要将额外的操作,从”实际“对象中分离到不同的地方,特别是当你希望很容易做出修改,并作出额外操作时,代理就很有用。比如,你想统计RealObject中方法所执行的时间,但是你又不想将时间统计代码写入RealObject的方法中,就可以使用代理设计模式,让代理帮你去做,同时也不用更改调用接口。
2.Java中的动态代理。
Java中的动态代理比代理的思想更前进一步,因为它可以动态地创建代理并动态地处理对所代理方法的调用。在动态代理上所做的所有调用都会被重定向到单一的调用处理器上,它的工作是揭示调用的类型,并确定相应的对策。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

class DynamicProxyHandler implements InvocationHandler{
    private Object proxied;
    public DynamicProxyHandler(Object proxied){
        this.proxied = proxied;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("**** proxy: " + proxy.getClass() + ", method: " + method +", args : " + args);
        if (args != null){
            for (Object arg : args){
                System.out.println(" " + arg);
            }
        }
        return method.invoke(proxied,args);
    }
}
public class SimpleDynamicProxy {
    public static void consumer(Interface iface){
        iface.doSomething();
        iface.somethingElse("banana");
    }

    public static void main(String[] args) {
        RealObject realObject = new RealObject();
        consumer(realObject);
        
        Interface proxy = (Interface) Proxy.newProxyInstance(
                                    Interface.class.getClassLoader(),
                                    new Class[]{Interface.class},
                                    new DynamicProxyHandler(realObject));
        consumer(proxy);

    }
}

输出

Do something
Something else banana
**** proxy: class com.sun.proxy.$Proxy0, method: public abstract void com.thinkInJava.chapter14.Interface.doSomething(), args : null
Do something
**** proxy: class com.sun.proxy.$Proxy0, method: public abstract void com.thinkInJava.chapter14.Interface.somethingElse(java.lang.String), args : [Ljava.lang.Object;@2503dbd3
 banana
Something else banana

通过调用静态方法Proxy.newProxyInstance()可以创建动态代理,这个方法需要三个参数,
第一个是类加载器(通常可以从已经被加载的对象中获取其类加载器,然后传递给它)” 谁要被代理呀?"
,第二个是希望该代理实现的接口列表(不是类或抽象类) " 我是代理,我要实现什么接口才能代理你呀? 参照上面静态代理中,代理人要实现相同接口“
,第三个是InvocationHandler接口的一个实现 “构造处理代理的实现” 。
动态代理可以将所有调用重定向到调用处理器,因此,通常会向调用处理器的构造函数传递给一个”实际“对象的引用,从而使得调用处理器在执行其中任务时可以将请求转发。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值