Java代理模式与动态代理之间的关系是什么
导读:本文共3852字符,通常情况下阅读需要13分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: 什么是代理模式代理模式是开发中常见的一种设计模式,使用代理模式可以很好的对程序进行横向扩展。代理,顾名思义就是一个真实对象会存在一个代理对象,并且代理对象可以替真实对象完成相应操作,外部通过代理对象来访问真实对象并且还可以在代理对象中进行额外操作的扩展。代理模式的特征是拥有接口、代理类、被代理类。并且代理类与被代理类同时实现该接口。代理类与被代理类之间通常存在一... ...
目录
(为您整理了一些要点),点击可以直达。代理模式是开发中常见的一种设计模式,使用代理模式可以很好的对程序进行横向扩展。代理,顾名思义就是一个真实对象会存在一个代理对象,并且代理对象可以替真实对象完成相应操作,外部通过代理对象来访问真实对象并且还可以在代理对象中进行额外操作的扩展。
代理模式的特征是拥有接口、代理类、被代理类。并且代理类与被代理类同时实现该接口。代理类与被代理类之间通常存在一定关联,设计时会在代理类中注册一个被代理类的对象用于调用代理类的方法。这也印证了代理对象依然是执行的真实对象的方法
代理模式又分为静态代理和动态代理
静态代理,关键字静态是指在程序运行之前编译时就已经确定了代理类、被代理类、接口。
下面列举两个示例展示静态代理:
学生通过班长交班费,班长作为学生的代理,学生是被代理,具有同一行为就是交班费,这个行为我们用接口进行约束
程序:
测试:
房屋租赁,租客通过中介找房源,租客为被代理类,中介为代理类,接口声明租房方法
测试:
上述两个示例,向代理类中注入被代理对象的方式都是通过构造器注入,当然也可以通过set方法注入
下面演示如果需要在已经编写好的代理类的输出中添加其他操作时的操作比如打印一个日志,在不修改源代码的情况下扩展
假设现在我们需要在每一次执行操作前后打印一次执行日志,并且不能修改源代码那么就可以用到代理模式,将UserServiceImpl作为被代理类,扩展代理类如下:
动态代理:代理类在程序运行时被创建的代理方式。
关键在于动态,程序具有了动态特性,可以在运行期间根据不同的目标对象生成动态代理对象,并且可以通过动态代理对象对目标对象(真实对象)进行功能性补强。大白话来讲就是,可以在程序运行期间额外的对真实对象功能进行扩展。
此处的动态代理对象不是通过预先编写好的程序生成的,而是运行期间由于用户需求或者说是代码的指示生成的
动态代理分为两种:一类是基于接口实现的动态代理,另一类是基于类的动态代理
基于接口的动态代理–JDK动态代理通过反射完成,基于类实现的–>cglib
JDK动态代理核心:Proxy类、InvocationHandler接口、要参与代理的目标类必须实现对应接口,比如上述的Student必须实现Person接口。
继续以上述学生交班费为例,更改为动态代理模式:
JDK动态代理中间类:该类需要实现InvocationHandler接口
测试:
上述程序,我们利用Proxy来生成代理类:
Proxy提供了静态的获取Proxy代理类的方法newProxyInstance
,三个参数分别是1.类加载器 2.代理对象实现的接口 3. 调用处理程序(InvocationHandler)
在InvocationHandler官方文档就已经指出,每一个代理实例都关联有一个InvocationHandler调用处理程序,所以这里填this即可
在使用代理类的时候首先我们创建需要被代理的真实对象和动态代理中间类的对象,用set方法将真实对象交给中间类中的代理对象。在调用上述getProxy方法获取代理类。动态代理相对于静态代理有些难以理解,这是因为静态代理的代理类可以在程序中显式的被看到,而动态代理中的代理类文件是缓存在Java虚拟机,类名叫$Proxy0。
在虚拟机中生成的代理类中就会将我们所调用的方法内置,我们在执行proxy.giveMoney()
的同时,实际上是将giveMoney()方法作为参数传进invoke()的参数中去,而此时我们就可以将其他的操作交给invoke,由于所有代理对象在执行时最终都会走invoke方法,所以也为我们的开发节省大量代码
Java代理模式与动态代理之间的关系是什么的详细内容,希望对您有所帮助,信息来源于网络。