Java 动态代理的简单使用和理解
- 前言
- JDK 动态代理
- 代理类
- CGLIB 动态代理
- 代理类
- Spring @Configuration
- 小结
- 结语
前言1
另外,代理类还获取了 Object 的 hashCode、equals 和 toString 方法,它们的调用逻辑都是一样的,就是直接调用 InvocationHandler 对象对应的方法,比如:
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
因此,我们也是可以代理目标对象的这些方法的。
CGLIB 动态代理2:
public class TargetClass$$EnhancerByCGLIB$$eb42b691 extends TargetClass implements Factory {
private MethodInterceptor CGLIB$CALLBACK_0;
static void CGLIB$STATICHOOK1() {
// 要代理的目标方法
var10000 = ReflectUtils.findMethods(new String[]{"targetMethodA", "()V", "targetMethodB", "()V"}, (var1 = Class.forName("TargetClass")).getDeclaredMethods());
CGLIB$targetMethodA$0$Method = var10000[0];
CGLIB$targetMethodA$0$Proxy = MethodProxy.create(var1, var0, "()V", "targetMethodA", "CGLIB$targetMethodA$0");
CGLIB$targetMethodB$1$Method = var10000[1];
CGLIB$targetMethodB$1$Proxy = MethodProxy.create(var1, var0, "()V", "targetMethodB", "CGLIB$targetMethodB$1");
}
// 目标方法的简单代理
final void CGLIB$targetMethodA$0() {
super.targetMethodA();
}
public final void targetMethodA() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
// 当 MethodInterceptor 不为空时通过 MethodInterceptor 调用目标方法
if (var10000 != null) {
var10000.intercept(this, CGLIB$targetMethodA$0$Method, CGLIB$emptyArgs, CGLIB$targetMethodA$0$Proxy);
} else {
super.targetMethodA();
}
}
// 目标方法的简单代理
final void CGLIB$targetMethodB$1() {
super.targetMethodB();
}
public final void targetMethodB() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
// 当 MethodInterceptor 不为空时通过 MethodInterceptor 调用目标方法
if (var10000 != null) {
var10000.intercept(this, CGLIB$targetMethodB$1$Method, CGLIB$emptyArgs, CGLIB$targetMethodB$1$Proxy);
} else {
super.targetMethodB();
}
}
final int CGLIB$hashCode$5() {
return super.hashCode();
}
// 对 Object 方法的代理
public final int hashCode() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
Object var1 = var10000.intercept(this, CGLIB$hashCode$5$Method, CGLIB$emptyArgs, CGLIB$hashCode$5$Proxy);
return var1 == null ? 0 : ((Number)var1).intValue();
} else {
return super.hashCode();
}
}
// ...
}
public class TargetClass$$EnhancerByCGLIB$$eb42b691 extends TargetClass implements Factory {
private MethodInterceptor CGLIB$CALLBACK_0;
static void CGLIB$STATICHOOK1() {
// 要代理的目标方法
var10000 = ReflectUtils.findMethods(new String[]{"targetMethodA", "()V", "targetMethodB", "()V"}, (var1 = Class.forName("TargetClass")).getDeclaredMethods());
CGLIB$targetMethodA$0$Method = var10000[0];
CGLIB$targetMethodA$0$Proxy = MethodProxy.create(var1, var0, "()V", "targetMethodA", "CGLIB$targetMethodA$0");
CGLIB$targetMethodB$1$Method = var10000[1];
CGLIB$targetMethodB$1$Proxy = MethodProxy.create(var1, var0, "()V", "targetMethodB", "CGLIB$targetMethodB$1");
}
// 目标方法的简单代理
final void CGLIB$targetMethodA$0() {
super.targetMethodA();
}
public final void targetMethodA() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
// 当 MethodInterceptor 不为空时通过 MethodInterceptor 调用目标方法
if (var10000 != null) {
var10000.intercept(this, CGLIB$targetMethodA$0$Method, CGLIB$emptyArgs, CGLIB$targetMethodA$0$Proxy);
} else {
super.targetMethodA();
}
}
// 目标方法的简单代理
final void CGLIB$targetMethodB$1() {
super.targetMethodB();
}
public final void targetMethodB() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
// 当 MethodInterceptor 不为空时通过 MethodInterceptor 调用目标方法
if (var10000 != null) {
var10000.intercept(this, CGLIB$targetMethodB$1$Method, CGLIB$emptyArgs, CGLIB$targetMethodB$1$Proxy);
} else {
super.targetMethodB();
}
}
final int CGLIB$hashCode$5() {
return super.hashCode();
}
// 对 Object 方法的代理
public final int hashCode() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
Object var1 = var10000.intercept(this, CGLIB$hashCode$5$Method, CGLIB$emptyArgs, CGLIB$hashCode$5$Proxy);
return var1 == null ? 0 : ((Number)var1).intValue();
} else {
return super.hashCode();
}
}
// ...
}
可以看到
- CGLIB 每个方法设置了两个代理,一个直接调用父类方法,另一个判断是否存在
MethodInterceptor来进行调用 - 代理类继承了
TargetClass, 和 JDK 动态代理中继承Proxy的方式不一样
当我们设置了 MethodInterceptor 以后,CGLIB 便可以通过 MethodInterceptor 来调用目标方法,另外,调用 MethodInterceptor.intercept 方法时传递的第一个参数为代理类实例, 因此,需要执行被代理的方法时,应该通过 MethodProxy.invokeSuper 来完成,如果使用 Method.invoke 的话就会导致无限递归调用。
Spring @Configuration1 最开始看到 InvocationHandler 这个接口的时候总以为它的第一个参数为 TargetObject
2 为了方便阅读省略了很多其他不必要的内容