代理模式Proxy

代理模式

1.1 定义:

为其他对象提供一种代理以控制对这个对象的访问。

被代理的对象可以是: 远程对象、创建开销大的对象、需要安全控制的对象

1.2 结构:

1.2.1 角色:

  • 抽象主题:对象和它的代理公用的接口
  • 实际主题:所要代理的对象
  • 代理:含有主题接口声明的变量,用来存放实际主题对象实例的引用。

1.2.2 UML

在这里插入图片描述

代理类需要实现被代理的所有非构造方法,且名字一般保持一致,所以一般情况下,会抽象一个接口,使得代理类和被代理类都继承此接口,但是如果代理第三方类库,无法修改第三方类库代码。

1.3 分类:

1.3.1 静态代理:

优点: 在不修改目标对象功能的前提下,通过代理对象对目标功能扩展

缺点: 代理对象需要和目标对象实现一样的接口,所以会有很多代理类

​ 一旦接口增加新方法,目标对象和代理类都要维护

1.3.2 动态代理:

代理类时运行期间生成的,主流有两个实现, 1. java标准库 2. cglib

1.3.2.1 java标准库的实现

需要代理类和被代理类实现同一个接口

// 抽象接口
public interface Geometry {
    public double getArea();
}

// 被代理类
public class Triangle implements Geometry{

    double sideA, sideB, sideC;

    public Triangle(double sideA, double sideB, double sideC) {
        this.sideA = sideA;
        this.sideB = sideB;
        this.sideC = sideC;
    }

    @Override
    public double getArea() {
        double p = (sideA + sideB + sideC) / 2.0;
        return Math.sqrt(p * (p-sideA) * (p-sideB) * (p-sideC));
    }
}

// 中间类
/*需要实现标准库的InvocationHandler接口。
(1)重写构造函数,参数为被代理类,被代理类作为类属性。
(2)实现invoke方法,在这里利用反射调用实际被代理类的方法和添加一些增强的逻辑。*/
public class MethodInvocationCountHandler implements InvocationHandler {

    private Object implementation;

    public MethodInvocationCountHandler(Object implementation) {
        this.implementation = implementation;
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("执行了");
        return method.invoke(implementation, args);
    }
}

// 调用
public class Client {

    public static void main(String[] args) {

        Geometry geometry = new Triangle(1, 2, 3);

        InvocationHandler invocationHandler = new MethodInvocationCountHandler(geometry);

        Geometry geometryProxy = (Geometry) Proxy.newProxyInstance(Geometry.class.getClassLoader(), new Class[]{Geometry.class}, invocationHandler);
        geometryProxy.getArea();
    }

}

1.3.2.2 cglib (Code Generation Library)

jdk标准库动态代理的实现,需要被代理类实现接口,cglib 不需要, spring aop 中会根据被代理对象是否有实现接口来选择使用jdk 动态代理还是 cglib

// 中间增强类, 需要导入 cglib包, asm包
public class ProxyInterceptor implements MethodInterceptor {

    private Object target;

    public Object bind(Object target) {
        this.target = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        System.out.println("执行了");
        return methodProxy.invokeSuper(o, objects);
    }
}

// 调用
public class Client {

    public static void main(String[] args) {

        ProxyInterceptor proxyInterceptor = new ProxyInterceptor();
        Triangle geometryProxy = (Triangle) proxyInterceptor.bind(new Triangle(1, 2, 3));
        geometryProxy.getArea();
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值