在java中,动态代理是一种机制,允许在运行时动态地创建代理对象来代替某个实际对象,从而在其前后执行额外的逻辑。
为什么jdk动态代理只能代理接口实现类,原因是jdk动态代理是基于接口实现的。
当你使用proxy类创建代理对象时,你需要指定一个接口列表来表示代理对象所应该实现的接口,这些接口就成为代理对象的类型。
具体来说,代理对象的方法调用会被转发到实现invocationhandler接口的类中的invoke()方法。这个invoke()方法接受三个参数:代理对象本身、被调用的方法对象和方法的参数数组。invoke()方法需要返回被代理方法调用的结果。
由于代理对象的类型是由接口列表决定的,因此只有实现了接口的类才能被代理。如果你想代理一个类而不是一个接口,你需要使用其他的代理技术,比如cglib。
1、jdk动态代理代码实例下面是一个简单的示例代码,展示了如何使用jdk动态代理来创建代理对象。
import java.lang.reflect.invocationhandler;import java.lang.reflect.method;import java.lang.reflect.proxy;public class proxydemo { public static void main(string[] args) { realobject real = new realobject(); invocationhandler handler = new dynamicproxy(real); // 创建代理对象 myinterface proxy = (myinterface) proxy.newproxyinstance( myinterface.class.getclassloader(), new class[] { myinterface.class }, handler); // 调用代理对象的方法 proxy.dosomething(); }}interface myinterface { void dosomething();}class realobject implements myinterface { public void dosomething() { system.out.println(realobject dosomething); }}class dynamicproxy implements invocationhandler { private object target; public dynamicproxy(object target) { this.target = target; } public object invoke(object proxy, method method, object[] args) throws throwable { system.out.println(before method invocation); object result = method.invoke(target, args); system.out.println(after method invocation); return result; }}在上面的代码中,realobject实现了myinterface接口,它是我们要代理的实际对象。dynamicproxy类实现了invocationhandler接口,并在invoke()方法中添加了额外的逻辑,用于在代理对象方法调用前后执行。
在main()方法中,我们使用proxy.newproxyinstance()方法创建代理对象。我们指定了myinterface接口作为代理对象类型,并将dynamicproxy对象作为代理对象的invocationhandler。
最后,我们调用代理对象的dosomething()方法,并观察控制台输出的结果。
需要注意的是,代理对象的方法调用都会被转发到dynamicproxy类的invoke()方法中进行处理,因此在这个示例中,实际的realobject对象的dosomething()方法的执行是在invoke()方法中通过反射进行的。
总结一下,jdk动态代理只能代理接口实现类,原因是jdk动态代理是基于接口实现的,代理对象的类型由接口列表决定。如果你想代理一个类而不是一个接口,你需要使用其他的代理技术,比如cglib。
2、cglib 代码演示以下是cglib代理的示例代码。
import net.sf.cglib.proxy.enhancer;import net.sf.cglib.proxy.methodinterceptor;import net.sf.cglib.proxy.methodproxy;import java.lang.reflect.method;public class cglibproxydemo { public static void main(string[] args) { realobject real = new realobject(); methodinterceptor handler = new cglibproxy(real); // 创建代理对象 realobject proxy = (realobject) enhancer.create( realobject.class, handler); // 调用代理对象的方法 proxy.dosomething(); }}class cglibproxy implements methodinterceptor { private object target; public cglibproxy(object target) { this.target = target; } public object intercept(object obj, method method, object[] args, methodproxy proxy) throws throwable { system.out.println(before method invocation); object result = proxy.invoke(target, args); system.out.println(after method invocation); return result; }}在上面的示例中,我们使用cglib的enhancer类和methodinterceptor接口来创建代理对象。realobject类不再需要实现接口,而是直接作为代理对象的类型。在cglibproxy类中,我们实现了methodinterceptor接口,并在intercept()方法中添加了额外的逻辑。
在main()方法中,我们使用enhancer.create()方法创建代理对象。我们指定了realobject类作为代理对象类型,并将cglibproxy对象作为代理对象的methodinterceptor。最后,我们调用代理对象的dosomething()方法,并观察控制台输出的结果。
需要注意的是,cglib代理使用字节码技术来生成代理对象,因此它的效率比jdk动态代理要高,但是它也需要额外的库依赖。
3、两者优缺点jdk动态代理和cglib代理都有它们自己的优缺点。
jdk动态代理的优点:
jdk动态代理是java标准库的一部分,因此它不需要引入任何外部依赖。jdk动态代理只需要实现接口即可生成代理对象,不需要改变原有类的结构。由于jdk动态代理是基于接口实现的,因此它更适合用于代理接口实现类的场景。jdk动态代理的缺点:
jdk动态代理只能代理实现了接口的类,无法代理没有实现接口的类。jdk动态代理在生成代理对象时,需要使用反射机制,因此它的效率相对较低。cglib代理的优点:
cglib代理是基于字节码技术实现的,因此它的效率比jdk动态代理更高。cglib代理可以代理没有实现接口的类。cglib代理的缺点:
cglib代理需要引入外部依赖。cglib代理在生成代理对象时,需要改变原有类的结构,因此它可能会引起一些问题,例如无法代理final类或final方法等问题。综上所述,jdk动态代理适用于代理接口实现类的场景,而cglib代理适用于代理没有实现接口的类的场景。如果你需要代理接口实现类,而且不想引入额外的依赖,那么jdk动态代理是一个不错的选择;如果你需要代理没有实现接口的类,那么cglib代理可能更适合你的需求。
iphone14预计什么时候上市
电阻器的主要参数 电阻器在电路中的作用
彩色 TFT 显示器使用的微控制器技术
预计2020年全球连接器市场的规模将达到600亿美金
机器学习特征工程的五个方面优点
JDK动态代理的原理
sdh传输设备退网探讨
利用热继电器实现电机一备一用电路
IC、LCD等电子产品原材料“涨价潮”来势更加汹涌
动力电池产业现状及技术动态
国家政务服务平台成效凸显,网上政务服务能力持续提升
中国显示技术将迎来品牌高光?京东方约你“周二见”
音频蓝牙芯片选型方案在电动车上的运用
一个VR版初代《黑客帝国》的故事
安防机器人落地减轻传统安保工作强度
至2027年底!新能源汽车购置税减免再延长
ips硬屏和软屏哪个好
五大项目的实施,可创建一个主流的区块链世界
ForwardXP:通过XR培训实现F.A.S.T(快速)响应
pcb分板机原理_pcb板分板机的种类