【java开发设计模式篇】之代理模式及动态代理

112 阅读5分钟

前言: java开发中,设计模式是必须要懂得的知识点,也是面试必考点,由于设计模式并不是三言两语可以讲清楚的,只能一个一个来进行剖析,本章主要分享代理模式。此文章仅代表鄙人的总结和理解,如有错漏,欢迎指正...

设计模式有很多种,如果想要更深入的了解,可参考以下链接进行全面性的学习
请点击:软件设计模式概述

一、什么是动态代理和静态代理

静态:
由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了。

静态代理的过程:
定义一个接口有部分功能,然后代理类实现该接口对象,并且传入实现类作为参数并使用该实现类对象的方法,向上转型

静态代理的缺点在于:
只能服务于一种类型的对象,不利于业务的拓展。就是代理类只实现了某个接口,如果有成百上千的业务类怎么办呢?

动态:
在程序运行时运用反射机制动态创建而成。要实现动态代理,一定要实现InvocationHandle接口,实现invoke方法。该invoke方法就是调用被代理接口的所有方法时需要调用的,该invoke方法的返回值是被代理接口的一个实现类。通过反射机制得到被代理的类,然后可以调用该类的方法实现动态代理

动态代理的优点:
动态代理只是对类做了进一步抽象和封装,使其复用性和易用性得到进一步提升而这不仅仅符合了面向对象的设计理念

二、代理模式的定义与特点

代理模式的定义:
由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。

代理模式的主要优点有:
代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;
代理对象可以扩展目标对象的功能;
代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度;

其主要缺点是:
在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢;
增加了系统的复杂度;
代理模式的结构与实现
代理模式的结构比较简单,主要是通过定义一个继承抽象主题的代理来包含真实主题,从而实现对真实主题的访问,下面来分析其基本结构和实现方法。

模式的结构
代理模式的主要角色如下。
抽象主题(Subject)类:通过接口或抽象类声明真实主题和代理对象实现的业务方法。
真实主题(Real Subject)类:实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。
代理(Proxy)类:提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

静态代理方式的优点:
1、易于理解和实现
2、代理类和真实类的关系是编译期静态决定的,和下文马上要介绍的动态代理比较起来,执行时没有任何额外开销。

静态代理方式的缺点:
每一个真实类都需要一个创建新的代理类。假设老板对测试工程师也提出了新的要求,让测试工程师每次测出bug时,也要及时更新对应的测试文档。那么采用静态代理的方式,测试工程师的实现类ITester也得创建一个对应的ITesterProxy类。

三、动态代理的几种实现方式:

更详细的知识请参考博客:Java代理设计模式(Proxy)的四种具体实现:静态代理和动态代理

1.JDK动态代理  
2.CGLIB动态代理  
3.编译期拼接字符串创建新的java类 

JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口,核心是InvocationHandler接口和Proxy类

CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的

Java动态代理实现方式一:


Java动态代理实现方式二:

通过CGLIB成功创建的动态代理,实际是被代理类的一个子类。那么如果被代理类被标记成final,也就无法通过CGLIB去创建动态代理。

Java动态代理实现方式三:

通过编译期提供的API动态创建代理类

故名思意,这个方式就是在编译期,通过一些API接口,动态的创建一个新的代理类,直接把一个代理类的源代码用字符串拼出来,然后基于这个字符串调用JDK的Compiler(编译期)API,动态的创建一个新的.java文件,然后动态编译这个.java文件,这样也能得到一个新的代理类。

ok , 狐狸与小兔的本节技术分享就到这,希望学习的小伙伴能学习到东西。。。


结语:以往都是看别人的博客进行学习技术,其中不乏有精华博客也有吊儿郎当的CV大法文章,所以决定将自己所学所用所整理的知识分享给大家,主要还是想为了后浪们少走些弯路,多些正能量的博客,如有错漏,欢迎指正,仅希望大家能在我的博客中学到知识,解决到问题,那么就足够了。谢谢大家!(转载请注明原文出处)