小白对java动态代理的一些理解

本文介绍了如何在不修改源代码的情况下,通过动态代理对类的成员方法fun进行功能增强。使用Proxy类的newProxyInstance方法创建代理对象,通过接口A和invoke方法实现增强逻辑,非目标方法由原类实例执行。
摘要由CSDN通过智能技术生成

动态代理可以通过不改变源码的情况下对一个类的成员方法进行改造

现在有一个类,它有几个成员方法  我们现在在不改变其源码的情况下对其中一个成员方法fun的功能进行增强,其他的方法还是原来的样子,这时可以使用动态代理

要使用动态代理,我们需要找一个代理对象,代理对象也有这些方法,但是代理对象需要对成员方法fun进行增强,也就是重写这个方法的方法体,在调用到这个方法时,由代理对象来调用这个方法,在调用其他的方法的时候,还是由原来类的实例对象进行调用

我们需要创建一个代理对象,它的能调用的成员方法应该与原来类的成员方法名相同,方法体只有fun不同,其他的方法就不需要这个代理真正地进行调用,所以我们可以创建一个接口A,这个接口A的抽象方法就是原来类的方法,它的实现类有两个,一个是原来的类,一个是代理类

创建代理对象,使用Proxy类下的静态方法newProxyInstance 创建一个代理对象proxy,要调用这个静态方法,我们要给它传递3个参数
参数1 类加载器


参数2 接口的字节码对象数组,我们这里只有一个接口A,这里传入的也就是接口A,为什么要传接口A,因为我们要创建代理对象,这个代理对象需要重写接口A中的抽象方法,这样才能得到原来类的同种方法,我们传进去的是接口A的字节码对象,那么底层就可以通过反射的方法来得到这个字节码对象中的全部内容,拿到全部内容后,就可以拿到全部的方法,然而这些方法都是抽象的,所以底层会创建类来实现接口A,再创建实例对象对这些方法进行重写,创建出来的实例对象就是代理对象

参数3 一个接口的实现类对象 这个实现类对象重写了invoke方法,将来代理对象要做什么事,也就是在代理对象调用方法时,其调用的那个方法会再调用这个invoke方法,这个invoke方法需要传递三个参数,一个是当前的代理对象, 一个是代理对象在调用重写后的方法时传进来的方法,还有一个是传进来方法的参数,在invoke方法内部,我们需要先用if判断传进来的这个方法是不是要增强的fun方法,如果是我们需要增强的fun方法,我们就将重写的方法体写在这个判断条件内部,到时候如果代理调用的确实是这个方法,会直接执行这个方法体,如果不是,那么我们需要让原来类的实例对象来执行传进来的方法,也就是说,代理对象在调用非fun方法时,实际上调用这些方法的实例对象是原来类的实例对象,由于我们已经通过反射拿到了接口A的字节码对象,可以通过反射来操作类,执行类的方法,也就是说,我们可以通过method.invoke(原来类的实例对象,参数args)来达到原来类的对象调用其本身的方法的现象,那么为什么可以使用原来类的实例对象来调用?因为我们在上面让原来的类实现了这个接口A,如果不让原来的类实现接口A,那么再通过method.invoke(原来类的实例对象,参数args),就不能达到调用原来的类中的方法

如有写的不对的地方还请各位大佬进行指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值