Uchiha-Itachi-
基本介绍
- 代理对象,不需要实现接口,但是目标对象要实现接口,否则不能用动态代理。
- 代理对象的生成,是利用JDK的API,动态的内存中构建代理对象
- 动态代理也叫做: JDK代理、接口代理
JDK中生成代理对象的API
- 代理类所在包: java.lang.reflect.Proxy
- JDK实现代理只需要使用newProxyInstance方法,但是该方法需要接收三个参数,完整写法为:
- static Object newProxyInstance(ClassLoader loader,Class>[] interfaces,InvocationHandler h)
动态代理应用举例
用动态代理实现事务:
UserService:
UserServiceImpl:
UserServiceInvocationHandler:
测试类:
结果为:
下面分析,为什么java动态代理中,最终都转换为调用invok方法?
我们先查看上面生成的proxy对象,
下面我们看看生成的 $proxy0代码:
很清楚,动态代理类实现了UserService接口,继承了Proxy类。
接口方法:
invoke方法传入3个参数,这个invoke方法也就是4.1.2中我们提到的InvocationHandler接口的 invoke方法,那理解3个参数的意义也就很简单了。
参数1传入的为this——即$Proxy0本身,所以是内存中的动态代理对象
参数2传入的为m3——也就是proxy.test.UserService中名为saveUser的方法,即接口中的方法。
参数3传入的为null——因为saveUser方法没有参数,所以为空。
完整代码如下
码农的一天
有些年头没写代码了,记忆中大概还能想起一些线索,翻出老代码看了一下,试着回答一下你的问题,大概的思路是这样的。
Java 在写动态代理的时候一般步骤是这样, 一般来说这三个东西必须有:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.lang.reflect.Method;
第一步, 我们要定义一个接口,比方就叫做 DInterface, 简单些就两个方法:
第二步我们要定义一个类来实现上面这个接口,这个类就是我们的真实对象,名字就叫RealObject类,简单些:
第三步,我们就要定义动态代理类了,并且每一个动态代理类都必须要实现 InvocationHandler 这个接口,这是死理,不能例外,就是通过这个东西来关联。
如果没记错这地方应该会输出一个xxxProxy.$Proxy0的类,所有的线路往$Proxy0源代码里找。
写个简单的测试
这里通过Proxy.newProxyInstance方法来创建我们的代理对象,
大约的过程是这样:
运行一下程序会发现它生成一个叫做$proxy0的类,它就是代理对象的真身。
查看这个$proxy0 源代码就会发现它的构造器就直接调用了 super(invocationhandler),这里invocationhandler在本例子就是 new DynamicProxyHandler(real),而它必须实现Invocationhandler接口,这个接口就一个方法invoke(), 所以动态代理自然然就转换为调用invoke()方法了, 另外打开$
proxy0.class
看一下里面方法的参数传递就更清楚了。有年头没做coding了,下班时看到头条的邀请,凭记忆和粗看了下代码回答,抛砖引玉,如有不周请高手继续补充更多细节,一起分享,一起讨论,共同学习。
珠乡二哥
也不想回答太多,写多了反而头晕。动态代理底层就是java反射,动态生成了之后代理类,所以调用的反射里的invoke
有理想有节操的铲屎官
法()这里通过反射获得方法通过方法.invoke(对象);这样来调用方法,懂了么