目录
基本介绍
代理模式的核心思想就是:为一个对象(被代理对象)提供一个代理对象,并且通过代理对象控制对原来被代理对象的访问。可以简单理解为通过代理对象访问目标对象。这样做最大的好处就是可以在目标对象实现的基础上,增强额外的功能,起到扩展目标对象的效果。
被代理的对象可以是远程对象、创建时开销大的对象、需要安全控制的对象等。实现代理模式有不同的形式,主要有:静态代理、动态代理(也被称为JDK代理或接口代理)、Cglib代理(不需要实现接口,在内存中动态创建代理对象)。
单纯的通过文字描述大家可能对代理模式的理解还是不够深刻,我们可以通过一个简单的UML类图来加深对该模式的理解。
代理模式UML类图:
UML类图讲解:
TargetObject:表示目标对象也就是被代理的对象。ProxyObject:代表的是代理对象。Client:代表客户端,使用代理对象的类。
以上就是代理模式的一些基本概念,通过这些介绍相信大家对代理模式已经有了一个简单的认识,接下来就让菜鸟详细介绍一下上面提出的三种实现代理模式的方式,从而更加深入的了解代理模式。
静态代理
使用静态代理时需要让目标对象和代理对象一起实现相同的接口或者继承相同的父类。这样做的目的就是为了通过调用代理对象中和目标对象相同的方法来实现调用目标对象的方法,从而达到代理的效果。
静态代理UML类图:
代码实现:
代理对象和目标对象实现的共同接口
目标对象
代理对象
客户端测试类
执行结果
总结
优点:实现起来简单,并且容易理解,只要确保目标对象和代理对象实现共同的接口或继承相同的父类就可以在不修改目标对象的前提下进行扩展。
缺点:缺点也是显而易见的,必须有共同接口或父类,并且需要为每一个目标类维护一个代理类,当需要代理的类很多时会创建出大量代理类。一旦接口或父类的方法有变动,目标对象和代理对象都需要作出调整。
这种方式虽说简单但是灵活性不足。
动态代理(JDK代理、接口代理)
使用JDK代理的基本前提是目标对象必须要实现接口。使用该方式代理对象是不需要手动编写代理类的,代理类是通过JDK的API动态的在内存中创建的。
动态代理UML类图
代码实现JDK代理
目标对象需要实现的接口
目标对象
代理工厂
JDK代理示例代码图一
JDK代理示例代码图二
客户端测试类
执行结果
总结
优点:使用JDK动态代理,可以将代理类的创建推迟到运行时期在内存中创建,这样就可以大大减少代理类的创建和维护。
缺点:目标类必须实现接口,还增加了代码的理解难度。
Cglib代理
基本介绍以及注意事项
1、使用Cglib进行动态代理的目标类不需要强制要求实现接口。2、Cglib代理也叫做子类代理,它是在内存中动态的创建一个目标类的子类对象从而实现对目标类的代理。Cglib代理也是属于动态代理的一种。3、Cglib是一个强大的高性能代码生成工具,它可以在程序运行时期扩展类与实现接口。许多AOP框架都有使用Cglib。4、Cglib的底层是通过字节码处理框架ASM来转换字节码并生成新类的。5、注意:使用Cglib代理的类不能是final修饰的,并且被代理类中final和static修饰的方法不会被代理。
Cglib代理UML类图
示例代码
目标对象
代理工厂
Cglib代理示例代码图一
Cglib代理示例代码图二
客户端测试类
执行结果
总结:
优点:不需要额外维护代理类,并且也不需要强制要求被代理的目标对象实现接口,使得代码更加的灵活。
缺点:和JDK的动态代理一样,增加了代码的理解难度。
总结
通过“菜鸟”的介绍相信大家对代理模式也有了一定的认识。以上介绍的三种方式其使用时的选择时机需要根据实际情况考虑,一般当我们需要代理的类少的时候,可以考虑使用静态代理,但是静态代理的选择一般都比较少,因为其维护成本要高,并且局限也大。当被代理的目标类实现了接口时可以考虑使用JDK代理,反之当目标类没有实现接口时就只能选择使用Cglib代理了。
今天的分享就到这里了,如果感觉“菜鸟”写的文章还不错,记得点赞加关注呦!你们的支持就是我坚持下去的动力。文章哪里写的有问题的也希望大家可以指出,我会虚心受教。
转载自: https://baijiahao.baidu.com/s?id=1680625201397619593&wfr=spider&for=pc