美文网首页
面试官让手写动态代理实现?——JDK代理和CGLIB代理解析

面试官让手写动态代理实现?——JDK代理和CGLIB代理解析

作者: Java架构领域 | 来源:发表于2022-01-04 21:13 被阅读0次

一、什么是动态代理

动态代理是相对于静态代理产生的概念。

可以简单理解为,静态代理是在代码中编写好代理类,动态代理的代理类是在运行时动态生成的。

使用代理一般是为了在原类中增加一些增强功能,如Spring的AOP就是通过动态代理实现的。

二、Spring中使用动态代理

有JDK代理和CGLIB代理两种实现。

2.1 JDK代理和CGLIB代理区别

JDK

利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

CJLIB

利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

2.2 何时选用

当Bean实现接口时,Spring就会用JDK的动态代理。

当Bean没有实现接口时,Spring使用CGlib是实现。

可以强制使用CGlib(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)。

三、具体实现

3.1 JDK动态代理实现

1) 一些概念

有两个重要的类和接口InvocationHandler(接口)和Proxy(类)

InvocationHandler

InvocationHandler接口是proxy代理实例的调用处理程序实现的一个接口,业务接口的方法最终都是回调业务处理类(具体的Handler)的invoke方法完成调用

proxy:代理类代理的真实代理对象com.sun.proxy.$Proxy0

method:我们所要调用某个对象真实的方法的Method对象

args:指代代理对象方法传递的参数

Proxy

Proxy类就是用来创建一个代理对象的类,它提供了很多方法,但是我们最常用的是newProxyInstance方法。

loader:一个classloader对象,定义了由哪个classloader对象对生成的代理类进行加载

interfaces:一个interface对象数组,表示我们声明了代理类实现了这些接口,代理类就可以调用接口中声明的所有方法。

h:一个InvocationHandler对象,表示的是当动态代理对象调用方法的时候会关联到哪一个InvocationHandler对象上,并最终由其调用。

2)实现

定义一个接口:

实现类:

这里Real就是我们需要代理的类。

动态代理代码:

构造方法把要代理的对象传入Handler中。

这里invoke方法很重要,可以看到方法调用是通过我们传递一个Method类型参数,然后调用method.invoke来实现,即通过反射来实现。

生成代理类的样子:

这里add方法是调用了handler的invoke方法,传递三个参数,第一个是代理类本身,第二个是add方法的反射类,最后一个是参数列表。我们是通过InvocationHandler来完成拦截与代理。

JDK Proxy具体使用:

3) 实现概述

定义一个Handler实现InvocationHandler接口,通过构造方法把要代理的对象传到Handler中。Handler中重写invoke方法,调用method.invoke反射实现方法原逻辑

通过Proxy的newProxyInstance方法创建一个代理对象

生成的代理类会注入InvocationHandler对象,注入Method对象,代理类方法执行需要调用handler的invoke方法,可在其中增加拦截逻辑

3.2 CGLIB动态代理实现

没有接口,直接是实现类:

使用了一个与JDK Proxy中Handler类似的类:

代理类的大致样子:

与jdk代理大致相同,只是多了一个MethodProxy。 去上面Interceptor可以看到,调用invoke方法是

而不是

原因是代理类继承了原始类,obj指向的就是代理类对象的实例(JDK代理中指向的是真实对象)。

如果第二种写法就会递归调用代理类的add方法。

因此cglib封装了一个MethodProxy类,其中invokeSuper方法可以调用原始基类的真正方法。

使用:

总结

JDK代理和CGLIB代理实现本质上是很相似的。

都包含一下两点内容:

有一个接口或者基类,定义了一个代理类。

一个方法拦截器,完成方法的拦截和代理,是所有调用链的桥梁。

相关文章

网友评论

      本文标题:面试官让手写动态代理实现?——JDK代理和CGLIB代理解析

      本文链接:https://www.haomeiwen.com/subject/pvjccrtx.html