JAVA静态/动态代理

1 静态代理(简单描述)

先定义一个接口,里面定义目标方法

1
2
3
4
5
6
//目标类要实现的接口
public interface ITarget {

//目标方法
void doFunc(String words);
}

定义一个代理类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class StaticProxy implements ITarget{

private ITarget target = null;

//关联要增强的目标类
    public StaticProxy(ITarget target){
        this.target = target;
    }

//在这里增强目标类的目标方法
@Override
public void doFunc() {
...
...
...
        //增强目标方法
        target.doFunc();
        ...
...
...
}
}

以后,任意的一个ITarget接口的子类,都可以注入给StaticProxy类,然后实现一套增强,不再赘述。

2 动态代理

代理类在程序运行时创建的代理方式被成为 动态代理。也就是说,这种情况下,代理类并不是像静态代理一样,是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。

动态代理是spring AOP的实现原理,spring有两种动态代理模式,cglib和jdk,我们先来将java jdk的动态代理。

2.1 jdk的动态代理

首先,我们需要知道,jdk的动态代理只能代理实现了接口的类 没有实现接口的类不能实现JDK动态代理。其次,我们还要了解一个重要的中介接口InvocationHandler,这是jdk的动态代理的基石,它的定义如下:

1
2
3
4
5
public interface InvocationHandler {

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}

我们先来写一个jdk的动态代理实例,再来讨论其中的原理吧

2.1.1 jdk动态代理实例

我们先来定义一个目标类,或者说委托类,或者又叫被代理类,它实现了我们上面定义的那个接口ITarget:

1
2
3
4
5
public class Entrust implements ITarget {
public void doFunc(String words){
System.out.println(words);
}
}

再定义一个中介类,实现InvocationHandler接口,这个中介类,持有被代理的对象,在invoke中利用反射,调用目标类的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class JdkDynamicProxyHandler<T>  implements InvocationHandler {
//invocationHandler持有的被代理对象
T target;

public JdkDynamicProxyHandler(T target) {
this.target = target;
}
/**
* proxy:代表动态代理对象
* method:代表正在执行的方法
* args:代表调用目标方法时传入的实参
*
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("do before");
Object result = method.invoke(target, args);
System.out.println("do after");
return result;
}
}

好了,我们现在来写一个代理demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public static void main(String[] a){
//创建一个实例对象,这个对象是被代理的对象
ITarget attorney = new Attorney();

//创建一个与代理对象相关联的InvocationHandler
InvocationHandler jdkDynamicProxyHandler = new JdkDynamicProxyHandler<ITarget>(attorney);

//创建一个代理对象proxy来代理attorney,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
ITarget proxy = (ITarget) Proxy.newProxyInstance(ITarget.class.getClassLoader(), new Class<?>[]{ITarget.class}, jdkDynamicProxyHandler);

//代理执行上交班费的方法
proxy.doFunc("hello word");

//将生成的代理类写到桌面
writeProxyClassToHardDisk("/home/ls/Desktop/$Proxy22.class");
}

public static void writeProxyClassToHardDisk(String path) {
byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy22", Attorney.class.getInterfaces());
FileOutputStream out = null;
try {
out = new FileOutputStream(path);
out.write(classFile);
out.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

最后输出:

2.1.2 原理剖析

我们来看看Proxy.newProxyInstance方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
Objects.requireNonNull(h);

final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
//验证一些参数
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}

/*
* Look up or generate the designated proxy class.
* 从缓存里面获取某个类的代理类,如果该类的代理类不存在,就根据该类的类型创建一个
* 如果要深挖逻辑,可以看看ProxyClassFactory的apply方法。
* 其实生成代理类字节码文件的工作是通过 ProxyGenerate类中的generateProxyClass方法来完成的。
*/
Class<?> cl = getProxyClass0(loader, intfs);

/*
* Invoke its constructor with the designated invocation handler.
*
* /** parameter types of a proxy class constructor */
* private static final Class<?>[] constructorParams = { InvocationHandler.class };
*
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
//看上面的注释,constructorParams={ InvocationHandler.class },
//这是在生成代理类的构造函数,获得一个参数为InvocationHandler的构造方法
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
//这行代码的意思是将h,也就是实现InvocationHandler的实现类,
//我们传入的是jdkDynamicProxyHandler,注入到cons中。
//然后newInstance生成一个已经组装过参数的代理类。
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}

我们最应该关注的是 Class<?> cl = getProxyClass0(loader, intfs);这句,这里产生了代理类,后面代码中的构造器也是通过这里产生的类来获得,可以看出,这个类的产生就是整个动态代理的关键,由于是动态生成的类文件,我这里不具体进入分析如何产生的这个类文件,只需要知道这个类文件时缓存在java虚拟机中的。

我们对这个代理类进行反编译:(本次使用http://www.javadecompilers.com/在线反编译工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import java.lang.reflect.UndeclaredThrowableException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import aopLearn.ITarget;
import java.lang.reflect.Proxy;

//
// Decompiled by Procyon v0.5.30
//

public final class $Proxy22 extends Proxy implements ITarget
{
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
/**
*注意这里是生成代理类的构造方法,方法参数为InvocationHandler类型,看到这,是不是就有点明白了
*为何代理对象调用方法都是执行InvocationHandler中的invoke方法,而InvocationHandler又持有一个
*被代理对象的实例
*
*super(paramInvocationHandler),是调用父类Proxy的构造方法。
*父类持有:protected InvocationHandler h;
*Proxy构造方法:
* protected Proxy(InvocationHandler h) {
* Objects.requireNonNull(h);
* this.h = h;
* }
*
*/
public $Proxy22(final InvocationHandler invocationHandler) {
super(invocationHandler);
}

//这个静态块本来是在最后的,我把它拿到前面来,方便描述
static {
try {
//doFunc通过反射得到的名字m3
$Proxy22.m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
$Proxy22.m3 = Class.forName("aopLearn.ITarget").getMethod("doFunc", Class.forName("java.lang.String"));
$Proxy22.m2 = Class.forName("java.lang.Object").getMethod("toString", (Class<?>[])new Class[0]);
$Proxy22.m0 = Class.forName("java.lang.Object").getMethod("hashCode", (Class<?>[])new Class[0]);
}
catch (NoSuchMethodException ex) {
throw new NoSuchMethodError(ex.getMessage());
}
catch (ClassNotFoundException ex2) {
throw new NoClassDefFoundError(ex2.getMessage());
}
}

public final boolean equals(final Object o) {
try {
return (boolean)super.h.invoke(this, $Proxy22.m1, new Object[] { o });
}
catch (Error | RuntimeException error) {
throw;
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
/**
*
*这里调用代理对象的doFunc方法,直接就调用了InvocationHandler中的invoke方法,并把m3传了进去。
*this.h.invoke(this, m3, null);这里简单,明了。
*代理对象持有一个InvocationHandler对象,InvocationHandler对象持有一个被代理的对象,
*再联系到InvacationHandler中的invoke方法。其实就是代理对象调用InvocationHandler,
* InvocationHandler对象反射调用委托类对象。
*/
public final void doFunc(final String s) {
try {
super.h.invoke(this, $Proxy22.m3, new Object[] { s });
}
catch (Error | RuntimeException error) {
throw;
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}

public final String toString() {
try {
return (String)super.h.invoke(this, $Proxy22.m2, null);
}
catch (Error | RuntimeException error) {
throw;
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}

public final int hashCode() {
try {
return (int)super.h.invoke(this, $Proxy22.m0, null);
}
catch (Error | RuntimeException error) {
throw;
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}

}

看完了这些,我们来想一下,为什么jdk的动态代理,一定要委托类实现一个接口?这是因为我们可以看到,我们生成的代理类Proxy22 extends Proxy implements ITarget,已经继承了Proxy类,而java中不能多继承,为了让$Proxy22和委托类建立联系,只能实现一个接口。这里的建立联系,是指通过接口,得到委托类方法的反射等,并且,委托类实现自接口的方法,才能被增强

故而,本质上来说,jdk的动态代理,是为接口产生代理

在spring AOP中,我们使用jdk动态代理时当然也要定义InvocationHandler的实现类对象,spring中的是org.springframework.aop.framework.JdkDynamicAopProxy类。

2.2 cglib的动态代理

cglib的动态代理针对类来实现代理,对指定目标产生一个子类 通过方法拦截技术拦截所有父类方法的调用。我们要使用cglib代理必须引入cglib的jar包。

2.2.1 cglib动态代理实例

同样,定义一个跟上面例子一样的委托类。

1
2
3
4
5
public class Entrust {
public void doFunc(String words){
System.out.println(words);
}
}

实现MethodInterceptor接口生成方法拦截器

1
2
3
4
5
6
7
8
9
10
public class EntrustInterceptor implements MethodInterceptor{

@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("before");
Object o = proxy.invokeSuper(obj,args);
System.out.println("after");
return o;
}
}

实例如下:

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] a){
//cglib自带的debug工具,可以将代理类输出到指定路径
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/home/ls/Desktop/cglib");
Enhancer enhancer = new Enhancer();
//继承被代理类
enhancer.setSuperclass(Entrust.class);
enhancer.setCallback(new EntrustInterceptor());
//生成的代理类对象
Entrust entrust = (Entrust) enhancer.create();
//在调用我们代理类中的方法时会被我们实现的方法拦截器拦截
entrust.doFunc("hello word");
}

输出结果如下:

2.2.2 原理剖析

CGLIB会让生成的代理类继承被代理类,并在代理类中对代理方法进行强化处理(前置处理、后置处理等)。在CGLIB底层,其实是借助了ASM这个非常强大的Java字节码生成框架。

我们看到,代理类对象是由Enhancer类创建的。Enhancer是CGLIB的字节码增强器,可以很方便的对类进行拓展,创建代理对象的几个步骤:

  1. 生成代理类的二进制字节码文件;
  2. 加载二进制字节码,生成Class对象( 例如使用Class.forName()方法 );
  3. 通过反射机制获得实例构造,并创建代理类对象

我们来看看将代理类Class文件反编译之后的Java代码,一个动态代理,产生了三个类:

主要的代理类是

Entrust$$EnhancerByCGLIB$$832e20ab

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
package com.lufax.util.aopCache.cglibProxy;

import net.sf.cglib.core.Signature;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Factory;

/**
* 生成的代理类Entrust$$EnhancerByCGLIB$$832e20ab继承被代理类Entrust。
* 在这里我们需要注意一点:如果委托类被final修饰,那么它不可被继承,即不可被代理;
* 同样,如果委托类中存在final修饰的方法,那么该方法也不可被代理;
*
*/
public class Entrust$$EnhancerByCGLIB$$832e20ab extends Entrust implements Factory
{
private boolean CGLIB$BOUND;
private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
private static final Callback[] CGLIB$STATIC_CALLBACKS;
private MethodInterceptor CGLIB$CALLBACK_0;
private static final Method CGLIB$doFunc$0$Method;
private static final MethodProxy CGLIB$doFunc$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
private static final Method CGLIB$finalize$1$Method;
private static final MethodProxy CGLIB$finalize$1$Proxy;
private static final Method CGLIB$equals$2$Method;
private static final MethodProxy CGLIB$equals$2$Proxy;
private static final Method CGLIB$toString$3$Method;
private static final MethodProxy CGLIB$toString$3$Proxy;
private static final Method CGLIB$hashCode$4$Method;
private static final MethodProxy CGLIB$hashCode$4$Proxy;
private static final Method CGLIB$clone$5$Method;
private static final MethodProxy CGLIB$clone$5$Proxy;

static void CGLIB$STATICHOOK1() {
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
CGLIB$emptyArgs = new Object[0];
final Class<?> forName = Class.forName("com.lufax.util.aopCache.cglibProxy.Entrust$$EnhancerByCGLIB$$832e20ab");
final Class<?> forName2;
final Method[] methods = ReflectUtils.findMethods(new String[] { "finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (forName2 = Class.forName("java.lang.Object")).getDeclaredMethods());
CGLIB$finalize$1$Method = methods[0];
CGLIB$finalize$1$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "()V", "finalize", "CGLIB$finalize$1");
CGLIB$equals$2$Method = methods[1];
CGLIB$equals$2$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$2");
CGLIB$toString$3$Method = methods[2];
CGLIB$toString$3$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "()Ljava/lang/String;", "toString", "CGLIB$toString$3");
CGLIB$hashCode$4$Method = methods[3];
CGLIB$hashCode$4$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "()I", "hashCode", "CGLIB$hashCode$4");
CGLIB$clone$5$Method = methods[4];
CGLIB$clone$5$Proxy = MethodProxy.create((Class)forName2, (Class)forName, "()Ljava/lang/Object;", "clone", "CGLIB$clone$5");
final Class<?> forName3;
CGLIB$doFunc$0$Method = ReflectUtils.findMethods(new String[] { "doFunc", "(Ljava/lang/String;)V" }, (forName3 = Class.forName("com.lufax.util.aopCache.cglibProxy.Entrust")).getDeclaredMethods())[0];
CGLIB$doFunc$0$Proxy = MethodProxy.create((Class)forName3, (Class)forName, "(Ljava/lang/String;)V", "doFunc", "CGLIB$doFunc$0");
}
//代理类会为委托方法生成两个方法,一个是重写的doFunc方法,
//另一个是CGLIB$doFunc$0方法,我们可以看到它是直接调用父类的doFunc方法;

final void CGLIB$doFunc$0(final String s) {
super.doFunc(s);
}
//当执行代理对象的doFunc方法时,会首先判断一下是否存在实现了MethodInterceptor接口的CGLIB$CALLBACK_0;
//如果存在,则将调用MethodInterceptor中的intercept方法,如图2.1。
public final void doFunc(final String s) {
MethodInterceptor cglib$CALLBACK_2;
MethodInterceptor cglib$CALLBACK_0;
if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
CGLIB$BIND_CALLBACKS(this);
cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
}
if (cglib$CALLBACK_0 != null) {
//这里开始调用我们定义的EntrustInterceptor中的intercept方法。
//参数1、代理对象;2、委托类方法;3、方法参数;4、代理方法的MethodProxy对象(注意这个对象)。
cglib$CALLBACK_2.intercept((Object)this, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$doFunc$0$Method, new Object[] { s }, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$doFunc$0$Proxy);
return;
}
super.doFunc(s);
}

final void CGLIB$finalize$1() throws Throwable {
super.finalize();
}

protected final void finalize() throws Throwable {
MethodInterceptor cglib$CALLBACK_2;
MethodInterceptor cglib$CALLBACK_0;
if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
CGLIB$BIND_CALLBACKS(this);
cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
}
if (cglib$CALLBACK_0 != null) {
cglib$CALLBACK_2.intercept((Object)this, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$finalize$1$Method, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$emptyArgs, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$finalize$1$Proxy);
return;
}
super.finalize();
}

final boolean CGLIB$equals$2(final Object o) {
return super.equals(o);
}

public final boolean equals(final Object o) {
MethodInterceptor cglib$CALLBACK_2;
MethodInterceptor cglib$CALLBACK_0;
if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
CGLIB$BIND_CALLBACKS(this);
cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
}
if (cglib$CALLBACK_0 != null) {
final Object intercept = cglib$CALLBACK_2.intercept((Object)this, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$equals$2$Method, new Object[] { o }, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$equals$2$Proxy);
return intercept != null && (boolean)intercept;
}
return super.equals(o);
}

final String CGLIB$toString$3() {
return super.toString();
}

public final String toString() {
MethodInterceptor cglib$CALLBACK_2;
MethodInterceptor cglib$CALLBACK_0;
if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
CGLIB$BIND_CALLBACKS(this);
cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
}
if (cglib$CALLBACK_0 != null) {
return (String)cglib$CALLBACK_2.intercept((Object)this, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$toString$3$Method, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$emptyArgs, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$toString$3$Proxy);
}
return super.toString();
}

final int CGLIB$hashCode$4() {
return super.hashCode();
}

public final int hashCode() {
MethodInterceptor cglib$CALLBACK_2;
MethodInterceptor cglib$CALLBACK_0;
if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
CGLIB$BIND_CALLBACKS(this);
cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
}
if (cglib$CALLBACK_0 != null) {
final Object intercept = cglib$CALLBACK_2.intercept((Object)this, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$hashCode$4$Method, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$emptyArgs, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$hashCode$4$Proxy);
return (intercept == null) ? 0 : ((Number)intercept).intValue();
}
return super.hashCode();
}

final Object CGLIB$clone$5() throws CloneNotSupportedException {
return super.clone();
}

protected final Object clone() throws CloneNotSupportedException {
MethodInterceptor cglib$CALLBACK_2;
MethodInterceptor cglib$CALLBACK_0;
if ((cglib$CALLBACK_0 = (cglib$CALLBACK_2 = this.CGLIB$CALLBACK_0)) == null) {
CGLIB$BIND_CALLBACKS(this);
cglib$CALLBACK_2 = (cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0);
}
if (cglib$CALLBACK_0 != null) {
return cglib$CALLBACK_2.intercept((Object)this, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$clone$5$Method, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$emptyArgs, Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$clone$5$Proxy);
}
return super.clone();
}

public static MethodProxy CGLIB$findMethodProxy(final Signature signature) {
final String string = signature.toString();
switch (string.hashCode()) {
case -1574182249: {
if (string.equals("finalize()V")) {
return Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$finalize$1$Proxy;
}
break;
}
case -508378822: {
if (string.equals("clone()Ljava/lang/Object;")) {
return Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$clone$5$Proxy;
}
break;
}
case 346793840: {
if (string.equals("doFunc(Ljava/lang/String;)V")) {
return Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$doFunc$0$Proxy;
}
break;
}
case 1826985398: {
if (string.equals("equals(Ljava/lang/Object;)Z")) {
return Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$equals$2$Proxy;
}
break;
}
case 1913648695: {
if (string.equals("toString()Ljava/lang/String;")) {
return Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$toString$3$Proxy;
}
break;
}
case 1984935277: {
if (string.equals("hashCode()I")) {
return Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$hashCode$4$Proxy;
}
break;
}
}
return null;
}

public Entrust$$EnhancerByCGLIB$$832e20ab() {
CGLIB$BIND_CALLBACKS(this);
}

public static void CGLIB$SET_THREAD_CALLBACKS(final Callback[] array) {
Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$THREAD_CALLBACKS.set(array);
}

public static void CGLIB$SET_STATIC_CALLBACKS(final Callback[] cglib$STATIC_CALLBACKS) {
CGLIB$STATIC_CALLBACKS = cglib$STATIC_CALLBACKS;
}

private static final void CGLIB$BIND_CALLBACKS(final Object o) {
final Entrust$$EnhancerByCGLIB$$832e20ab entrust$$EnhancerByCGLIB$$832e20ab = (Entrust$$EnhancerByCGLIB$$832e20ab)o;
if (!entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$BOUND) {
entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$BOUND = true;
Object o2;
if ((o2 = Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$THREAD_CALLBACKS.get()) != null || (o2 = Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$STATIC_CALLBACKS) != null) {
entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])o2)[0];
}
}
}

public Object newInstance(final Callback[] array) {
CGLIB$SET_THREAD_CALLBACKS(array);
final Entrust$$EnhancerByCGLIB$$832e20ab entrust$$EnhancerByCGLIB$$832e20ab = new Entrust$$EnhancerByCGLIB$$832e20ab();
CGLIB$SET_THREAD_CALLBACKS(null);
return entrust$$EnhancerByCGLIB$$832e20ab;
}

public Object newInstance(final Callback callback) {
CGLIB$SET_THREAD_CALLBACKS(new Callback[] { callback });
final Entrust$$EnhancerByCGLIB$$832e20ab entrust$$EnhancerByCGLIB$$832e20ab = new Entrust$$EnhancerByCGLIB$$832e20ab();
CGLIB$SET_THREAD_CALLBACKS(null);
return entrust$$EnhancerByCGLIB$$832e20ab;
}

public Object newInstance(final Class[] array, final Object[] array2, final Callback[] array3) {
CGLIB$SET_THREAD_CALLBACKS(array3);
switch (array.length) {
case 0: {
final Entrust$$EnhancerByCGLIB$$832e20ab entrust$$EnhancerByCGLIB$$832e20ab = new Entrust$$EnhancerByCGLIB$$832e20ab();
CGLIB$SET_THREAD_CALLBACKS(null);
return entrust$$EnhancerByCGLIB$$832e20ab;
}
default: {
throw new IllegalArgumentException("Constructor not found");
}
}
}

public Callback getCallback(final int n) {
CGLIB$BIND_CALLBACKS(this);
Object cglib$CALLBACK_0 = null;
switch (n) {
case 0: {
cglib$CALLBACK_0 = this.CGLIB$CALLBACK_0;
break;
}
default: {
cglib$CALLBACK_0 = null;
break;
}
}
return (Callback)cglib$CALLBACK_0;
}

public void setCallback(final int n, final Callback callback) {
switch (n) {
case 0: {
this.CGLIB$CALLBACK_0 = (MethodInterceptor)callback;
break;
}
}
}

public Callback[] getCallbacks() {
CGLIB$BIND_CALLBACKS(this);
return new Callback[] { this.CGLIB$CALLBACK_0 };
}

public void setCallbacks(final Callback[] array) {
this.CGLIB$CALLBACK_0 = (MethodInterceptor)array[0];
}

static {
CGLIB$STATICHOOK1();
}
}

逻辑进入到我们在EntrustInterceptor 中定义的intercept方法

1
2
3
4
5
6
7
8

@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("before");
Object o = proxy.invokeSuper(obj,args);
System.out.println("after");
return o;
}

我们看看MethodProxy的invokeSuper方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* Invoke the original (super) method on the specified object.
* @param obj the enhanced object, must be the object passed as the first
* argument to the MethodInterceptor
* @param args the arguments passed to the intercepted method; you may substitute a different
* argument array as long as the types are compatible
* @see MethodInterceptor#intercept
* @throws Throwable the bare exceptions thrown by the called method are passed through
* without wrapping in an <code>InvocationTargetException</code>
*/
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
//f2是由CGlib生成的,在输出的class中有这个类。
//它就是Entrust$$EnhancerByCGLIB$$832e20ab$$FastClassByCGLIB$$817a77c.class
return fci.f2.invoke(fci.i2, obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}

我们把

Entrust$$EnhancerByCGLIB$$832e20ab$$FastClassByCGLIB$$817a77c.class

也反编译出来,然后贴出invoke方法,注意case14调用了

entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$doFunc$0((String)array[0]);:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
public Object invoke(final int n, final Object o, final Object[] array) throws InvocationTargetException {
final Entrust$$EnhancerByCGLIB$$832e20ab entrust$$EnhancerByCGLIB$$832e20ab = (Entrust$$EnhancerByCGLIB$$832e20ab)o;
try {
switch (n) {
case 0: {
entrust$$EnhancerByCGLIB$$832e20ab.setCallbacks((Callback[])array[0]);
return null;
}
case 1: {
Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$SET_STATIC_CALLBACKS((Callback[])array[0]);
return null;
}
case 2: {
Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$SET_THREAD_CALLBACKS((Callback[])array[0]);
return null;
}
case 3: {
return entrust$$EnhancerByCGLIB$$832e20ab.getCallback(((Number)array[0]).intValue());
}
case 4: {
return entrust$$EnhancerByCGLIB$$832e20ab.getCallbacks();
}
case 5: {
entrust$$EnhancerByCGLIB$$832e20ab.doFunc((String)array[0]);
return null;
}
case 6: {
entrust$$EnhancerByCGLIB$$832e20ab.setCallback(((Number)array[0]).intValue(), (Callback)array[1]);
return null;
}
case 7: {
return Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$findMethodProxy((Signature)array[0]);
}
case 8: {
Entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$STATICHOOK1();
return null;
}
case 9: {
entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$finalize$1();
return null;
}
case 10: {
return entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$toString$3();
}
case 11: {
return new Integer(entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$hashCode$4());
}
case 12: {
return entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$clone$5();
}
case 13: {
return new Boolean(entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$equals$2(array[0]));
}
case 14: {
entrust$$EnhancerByCGLIB$$832e20ab.CGLIB$doFunc$0((String)array[0]);
return null;
}
case 15: {
return new Boolean(entrust$$EnhancerByCGLIB$$832e20ab.equals(array[0]));
}
case 16: {
return entrust$$EnhancerByCGLIB$$832e20ab.toString();
}
case 17: {
return new Integer(entrust$$EnhancerByCGLIB$$832e20ab.hashCode());
}
case 18: {
return entrust$$EnhancerByCGLIB$$832e20ab.newInstance((Callback)array[0]);
}
case 19: {
return entrust$$EnhancerByCGLIB$$832e20ab.newInstance((Class[])array[0], (Object[])array[1], (Callback[])array[2]);
}
case 20: {
return entrust$$EnhancerByCGLIB$$832e20ab.newInstance((Callback[])array[0]);
}
case 21: {
Entrust.main((String[])array[0]);
return null;
}
case 22: {
entrust$$EnhancerByCGLIB$$832e20ab.wait(((Number)array[0]).longValue(), ((Number)array[1]).intValue());
return null;
}
case 23: {
entrust$$EnhancerByCGLIB$$832e20ab.wait(((Number)array[0]).longValue());
return null;
}
case 24: {
entrust$$EnhancerByCGLIB$$832e20ab.wait();
return null;
}
case 25: {
return entrust$$EnhancerByCGLIB$$832e20ab.getClass();
}
case 26: {
entrust$$EnhancerByCGLIB$$832e20ab.notify();
return null;
}
case 27: {
entrust$$EnhancerByCGLIB$$832e20ab.notifyAll();
return null;
}
}
}
catch (Throwable t) {
throw new InvocationTargetException(t);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}

事实证明,最后确实是进入了case14,调用了代理类的代理doFunc方法,最后再回到EntrustInterceptor.invoke中。完成逻辑

0%