Java中的代理模式

在这里插入图片描述

Java中的代理模式

意图: 为其他对象提供一种代理以控制对这个对象的访问。
何时使用: 想在访问一个类时做一些控制。
关键代码: 实现与被代理类组合。
应用实例: spring aop,retrofit,binder,。

优点:

1、职责清晰。
2、高扩展性。
3、智能化。

缺点:

1、由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
2、实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

注意事项:

1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。
2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

1、静态代理

在这里插入图片描述
作用:

通过引入代理对象的方式来间接访问目标对象,防止直接访问目标对象给系统带来的不必要复杂性。

2、动态代理

首先为了解决静态代理模式中存在的问题:

  • 1个静态代理 只服务1种类型的目标对象
  • 若要服务多类型的目标对象,则需要为每种目标对象都实现一个静态代理对象,会出现 静态代理对象量多、代码量大,从而导致代码复杂的问题

实现原理:

设计动态代理类(DynamicProxy)时,不需要显式实现与目标对象类(RealSubject)相同的接口,而是将这种实现推迟到程序运行时由 JVM来实现

  1. 即:在使用时再创建动态代理类 & 实例
  2. 静态代理则是在代理类实现时就指定与目标对象类(RealSubject)相同的接口

通过Java 反射机制的method.invoke(),通过调用动态代理类对象方法,从而自动调用目标对象的方法。

优点:

  • 只需要1个动态代理类就可以解决创建多个静态代理的问题,避免重复、多余代码
  • 更强的灵活性

缺点:

  • 效率低
  • 相比静态代理中 直接调用目标对象方法,动态代理则需要先通过Java反射机制 从而 间接调用目标对象方法
  • 应用场景局限, 因为 Java 的单继承特性(每个代理类都继承了 Proxy 类),即只能针对接口 创建 代理类,不能针对类 创建代理类

静态代理与动态代理的区别主要在:

  • 静态代理在编译时就已经实现,编译完成后代理类是一个实际的class文件
  • 动态代理是在运行时动态生成的,即编译完成后没有实际的class文件,而是在运行时动态生成类字节码,并加载到JVM中

特点:
动态代理对象不需要实现接口,但是要求目标对象必须实现接口,否则不能使用动态代理。

使用方式:

1.需要实现 InvocationHandler 接口
2.复写InvocationHandler接口的invoke()
3.动态代理对象调用目标对象的任何方法前,都会调用处理器类的invoke()
在这里插入图片描述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i8yIYYG3-1635750483016)(../../pic/doymProxy)]

应用场景:

Spring中的 AOP,面向切面编程。

测试:

这样我们就可以给实现了 IShop 接口的不同对象做代理。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Amrn6CMl-1635750483021)(../../pic/image-20210607202938946.png)]

安卓中的动态代理:

1.Retrofit

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d1memB6B-1635750483023)(../../pic/image-20210607203125174.png)]
在这里插入图片描述

2、AIDL 动态代理

Binder是一个非常典型的代理模式,是一种远程代理,实际上Proxy代理的是另外一个进程中的Stub对象。内部是将接口函数标记为对应的ID,然后根据这个ID来标识目前调用的是哪一个函数。由DESCRIPTOR来作为Token分隔不同的接口调用,另外通过Parcel来写入函数参数和接受函数返回值(Stub端对应接受参数和写入结果)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xi3dntC0-1635750483024)(../../pic/image-20210607205444559.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bT8gP9z1-1635750483025)(../../pic/image-20210607205429800.png)]

cglib代理

cglib特点

  • JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口。
    如果想代理没有实现接口的类,就可以使用CGLIB实现。
  • CGLIB是一个强大的高性能的代码生成包,它可以在运行期扩展Java类与实现Java接口。它广泛的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的interception(拦截)。
  • CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。
    不鼓励直接使用ASM,因为它需要你对JVM内部结构包括class文件的格式和指令集都很熟悉。
    cglib与动态代理最大的区别就是
  • 使用动态代理的对象必须实现一个或多个接口
  • 使用cglib代理的对象则无需实现接口,达到代理类无侵入。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值