为什么java动态代理中,最终都转换为调用invok方法?

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(对象);这样来调用方法,懂了么


分享到:


相關文章: