代 理 模 式

楔子

学习笔记

代理模式(Proxy Pattern)是指建立在某一个对象的代理对象,并且由代理对象控制对象的引用。

例如,我们不能直接访问对象A,则可以建立对象A的代理对象A Proxy。这样可以通过访问A Proxy类间接地使用对象A的功能,A Proxy就像A的对外联络人一般,如下图
在这里插入图片描述

代理模式能够实现很多功能:

  • 隔离功能:通过建立一个目标对象的代理对象,可以防止外部对象对目标对象的直接访问,这样就使得目标对象与外部隔离。我们可以在代理对象中增加身份验证、权限验证等功能,从而实现目标对象的安全防护。
  • 扩展功能:对一个目标对象建立代理对象后,可以在代理对象中增加更多的扩展功能。
  • 直接替换:对一个目标对象建立代理对象后,可以直接使用代理对象完全替换目标对象,由代理对象来实现全部功能。例如,MyBatis中数据库操作只是一个抽象方法,但实际运行中会建立代理对象来完成数据库的读写操作。

静态代理

静态代理就是代理模式最简单的实现。所谓“静态”,是指被代理对象和dialing对象在程序中是确定的,不会在程序运行过程中发生变化。

例如,为用户设置一个接口类UserInterface,增加一个大招呼的抽象方法sayHello。

public interface UserInterface {
    String sayHello(String name);
}

实现UserInterface接口的被代理类如下

public class User implements UserInterface {
    @Override
    public String sayHello(String name) {
        System.out.println("hello " + name);
        return "OK";
    }
}

为代理类增加一个代理类。代理类中调用了被代理类的sayHello方法,并在此方法的基础上增加新功能。

public class UserProxy implements UserInterface{
    private UserInterface target;
    public UserProxy(UserInterface target) {
        this.target = target;
    }

    @Override
    public String sayHello(String name) {
        System.out.println("pre words");
        target.sayHello(name);
        System.out.println("post words");
        return name;
    }
}

使用代理对象中的方法

public void testProxy() {
    //生成被代理对象
    User user = new User();
    //生成代理
    UserProxy userProxy = new UserProxy(user);
    //触发代理方法
    userProxy.sayHello("静态代理");
}

基于反射的动态代理

静态代理中代理对象和被代理对象是在程序中写死的,不够灵活。

java中java.lang.reflect包提供了一个Proxy和InvocationHandler接口,使用它们就可以实现动态代理。

如下代理是基于反射的动态代理

接口代码如下

public interface UserInterface {
    String sayHello(String name);
}

被代理类如下

public class User implements UserInterface {
    @Override
    public String sayHello(String name) {
        System.out.println("hello " + name);
        return "OK";
    }
}

以下创建一个ProxyHander类继承java.lang.reflect.InvocationHandler接口,并实现其中的invoke方法,invoke方法中需要传入被代理对象、被代理方法及调用代理方法所需的参数。

public class ProxyHandler<T> implements InvocationHandler {
    private T target;

    public ProxyHandler(T target) {
        this.target = target;
    }

    /**
     * @param proxy  被代理的对象
     * @param method 要调用的方法
     * @param args   方法调用时所需要参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("pre words");
        Object ans = method.invoke(target, args);
        System.out.println("post words");
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值