代理模式

目的:

对被代理的对象进行统一的访问控制,或功能增强。

静态代理

这里写图片描述

抽象角色(Subject)类:

abstract public class Subject {
    abstract public void request();
}

代理角色(ProxySubject)类:

public class ProxySubject extends Subject {

    private RealSubject realSubject; 

    public ProxySubject(){}

    public void request() {
        if (realSubject == null){
            realSubject = new RealSubject();
        }
        realSubject.request();
    }
}

真实角色(RealSubject)类:

public class RealSubject extends Subject {

    public RealSubject(){}

    public void request() {
        System.out.println("真实的请求.");
    }
}

客户端的调用代码:

Subject sub = new ProxySubject();
sub.request();

总结:
静态代理必须明确得到被代理的类。每一个抽象接口,对应这个真实类和代理类,会导致类膨胀。

动态代理

首先创建抽象角色:

public interface Subject {
    void doSomething();
    void somethingElse(String arg);
}

接下来创建具体角色:

public class RealSubject implements Subject{

    @Override
    public void doSomething() {
        System.out.println("doSomething");
    }

    @Override
    public void somethingElse(String arg) {
        System.out.println("somethingElse: " + arg);
    }
}

接下来是创建一个InvocationHandler接口的实现:

public class DynamicProxyHandler implements InvocationHandler{

    private Object proxied;

    public DynamicProxyHandler(Object proxied){
        this.proxied = proxied;
    }

    /**
     * invoke()方法中传递进来了代理对象,以防你需要区分请求的来源
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("*** proxy ***" + proxy.getClass());
        System.out.println("*** method ***" + method);
        System.out.println("*** args ***" + args);
        // 可以在这里做一些处理,如查看方法名,查看方法签名的其他方面,甚至可以搜索特定的参数值
        if(method.getName().equals("interesting"))
            System.out.println("Proxy detected the interesting method.");
        // 将请求转发给被代理的真实对象,并传入必须的参数
        return method.invoke(proxied, args);
    }

}

最后在main方法中创建动态代理对象,并通过动态代理调用真实角色的方法:

public class SimpleDynamicProxy {

    public static void consumer(Subject subject){
        subject.doSomething();
        subject.somethingElse("haha~~");
    }

    public static void main(String[] args){
        // 创建真实的对象
        RealSubject real = new RealSubject();
        consumer(real);
        // 通过调用该方法创建动态代理
        Subject proxy = (Subject)Proxy.newProxyInstance(
                Subject.class.getClassLoader(), // 类加载器
                new Class[]{Subject.class}, // 你希望该代理实现的接口列表
                new DynamicProxyHandler(real));  // InvocationHandler接口的一个实现
        consumer(proxy);
    }
}

第一个consumer(real)输出为:

doSomething
somethingElse: haha~~

第二个consumer(proxy)输出为:

*** proxy ***class com.sun.proxy.$Proxy0
*** method ***public abstract void com.yunsheng.Subject.doSomething()
*** args ***null
doSomething
*** proxy ***class com.sun.proxy.$Proxy0
*** method ***public abstract void com.yunsheng.Subject.somethingElse(java.lang.String)
*** args ***[Ljava.lang.Object;@6b40443
somethingElse: haha~~

总结:
动态代理在执行时,将方法的调用先重定向到InvocationHandler的实现类中。在Proxy.newProxyInstance时生成代理对象。在对代理对象进行方法调用时,才将调用的方法名和参数传去invoke进行执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值