动态代理

动态代理

JDK动态代理

动态代理的实现方式:

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

public interface Subject {
public void doSomething(String str);
}

public class RealSubject implements Subject {
public void doSomething(String str) {
System.out.println("do something!---->" + str);
}
}

/**
* 动态代理的Handler类
*/
public class MyInvocationHandler implements InvocationHandler {
// 被代理的对象
private Object target = null;
public MyInvocationHandler(Object obj) {
this.target = obj;
}

public Object invoke(Object proxy, Method method, Object[] args) throw Throwable {
return method.invoke(this.target, args);
}
}

public class Client {
public static void main(String[] args) {
MyInvocationHandler myInvocationHandler = new MyInvocationHandler(new RealSubject());
Subject subject = (Subject) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{Subject.class}, myInvocationHandler);
subject.doSomething("test");
}
}

原理

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

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throw IllegalArgumentException {
Objects.requireNonNull(h);

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

// 寻找或生成指明的代理类
Class<?> cl = getProxyClass0(loader, intfs);

// 使用指定的invocation handler调用它的构造函数
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
// 获取代理对象的构造方法
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;
}
});
}
// 生成代理类的实例并把InvocationHandler的实例传给它的构造方法
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);
}
}

getProxyClass0方法生成一个代理类

1
2
3
4
5
6
7
private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
// 如果由给定加载器和接口定义的代理类已经存在,则简单地返回缓存的副本,否则通过ProxyClassFactory创建代理类
return proxyClassCache.get(loader, interfaces);
}

其中proxyClassCache的定义如下:

1
private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

KeyFactory将接口数组映射为一个key对象:

1
2
3
4
5
6
7
8
9
10
11
private static final class KeyFactory implements BiFunction<ClassLoader, Class<?>[], Object> {
@Override
public Object apply(ClassLoader classLoader, Class<?>[] interfaces) {
switch (interfaces.length) {
case 1: return new Key1(interfaces[0]);
case 2: return new Key2(interfaces[0], interfaces[1]);
case 0: return key0;
default: return new KeyX(interfaces);
}
}
}

ProxyClassFactory是一个工程方法,生成、定义、返回给定加载器和接口数组定义的代理类:

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
private static final class ProxyClassFactory implements BiFunction<ClassLoader, Class<?>[], Class<?>> {
// 代理类名称的前缀
private static final String proxyClassNamePrefix = "$Proxy";
// 用于产生唯一代理名称的数字
private static final AtomicLong nextUniqueNumber = new AtomicLong();

@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
for (Class<?> intf : interfaces) {
// 检查接口由加载器解析后的类对象和接口相同
Class<?> interfaceClass = null;
try {
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
if (interfaceClass != intf) {
throw new IllegalArgumentException(intf + " is not visible from class loader");
}
// 检查接口由加载器解析后的类对象确实是接口
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(interfaceClass.getName() + " is not an interface");
}
// 检查接口没有重复
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
throw new IllegalArgumentException("repeated interface: " + interfaceClass.getName());
}
}

String proxyPkg = null;
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;

// 记录非公共代理接口的包,代理类定义在相同的包中。检查所有非公共的代理接口在相同的包中。
for (Class<?> intf : interfaces) {
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) {
accessFlags = Modifier.FINAL;
String name = intf.getName;
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) {
throw new IllegalArgumentException("non-public interfaces from different packages");
}
}
}

if (proxyPkg == null) {
proxyPkg = ReflectUtil.PROXY_PACKAGE = ".";
}

// 为生成的代理类选择一个名称
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;

// 生成指定的代理类的字节码
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);
try {
// 根据代理类的字节码生成代理类的实例
return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);
} catch(ClassFormatError e) {
throw new IllegalArgumentException(e.toString());
}
}
}

ProxyGenerator.generateProxyClass生成代理类class字节码

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
public static byte[] generateProxyClass(final String name, Class<?>[] interfaces, int accessFlags) {
ProxyGenerator gen = new ProxyGenerator(name, interfaces, accessFlags);
// 动态生成代理类的字节码
final byte[] classFile = gen.generateClassFile();

if (saveGeneratedFiles) {
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
try {
int i = name.lastIndexOf('.');
Path path;
if (i > 0) {
Path dir = Paths.get(name.substring(0, i).replace('.', File.separatorChar));
Files.createDirectories(dir);
path = dir.resole(name.substring(i+1, name.length()) + ".class");
} else {
path = Paths.get(name + ".class");
}
Files.write(path, classFile);
return null;
} catch (IOException e) {
throw new InternalError("I/O exception saving generated file: " + e);
}
}
}
);
}
return classFile;
}

用以下代码可以获取到JDK为我们生成的字节码写到硬盘中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ProxyGeneratorUtils {
public static void writeProxyClassToHardDisk(String path) {
byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy11", UserServiceImpl.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();
}
}
}
}

运行以下代码生成代理类文件:

1
ProxyGeneratorUtils.writeProxyClassToHardDisk("$Proxy11.class");

生成的class文件经过反编译:

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

import dynamic_proxy.p1.Subject;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy11 extends Proxy implements Subject {
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0;

// 构造方法,参数就是刚才传过来的MyInvocationHandler类的实例
public $Proxy11(InvocationHandler var1) throws {
super(var1);
}

public final boolean equals(Object var1) throws {
try {
return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}

public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}

// 这是关键方法
public final void doSomething(String var1) throws {
try {
// 实际上就是调用MyInvocationHandler的public Object invoke(Object proxy, Method method, Object[] args)方法
super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}

public final int hashCode() throws {
try {
return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue();
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}

static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("dynamic_proxy.p1.Subject").getMethod("doSomething", Class.forName("java.lang.String"));
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}

CGLIB动态代理

CGLIB(Code Generation Library)是一个基于ASM的字节码生成库,它允许我们在运行时对字节码进行修改和动态生成。CGLIB通过继承方式实现代理。

假设我们有一个没有实现任何接口的类HelloConcrete:

1
2
3
4
5
public class HelloConcrete {
public String sayHello(String str) {
return "HelloConcrete: " + str;
}
}

因为没有实现接口,该类无法使用JDK代理,通过CGLIB代理实现如下:

  1. 首先实现一个MethodInterceptor,方法调用会被转发到该类的intercept()方法

    1
    2
    3
    4
    5
    6
    7
    public class MyMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    System.out.println("You said: " + Arrays.toString(args));
    return methodProxy.invokeSuper(proxy, args);
    }
    }
  1. 在需要使用HelloConcrete的时候,通过CGLIB动态代理获取代理对象

    1
    2
    3
    4
    5
    6
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(HelloConcrete.class);
    enhancer.setCallback(new MyMethodInterceptor());

    HelloConcrete hello = (HelloConcrete) enhancer.create();
    System.out.println(hello.sayHello("I love you!"));

运行上述代理输出结果:

1
2
You said: [I love you!]
HelloConcrete: I love you!

原理

我们可以通过将代理类生成class文件,加入以下的代码,可以将代理类保存为指定路径下的文件:

1
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/Users/wangqi/Downloads");

生成的代理如下所示:

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
public class HelloConcrete$$EnhancerByCGLIB$$a810359d extends HelloConcrete implements Factory {
private boolean CGLIB$BOUND;
public static Object CGLIB$FACTORY_DATA;
private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
private static final Callback[] CGLIB$STATIC_CALLBACKS;
private MethodInterceptor CGLIB$CALLBACK_0;
private static Object CGLIB$CALLBACK_FILTER;
private static final Method CGLIB$sayHello$0$Method;
private static final MethodProxy CGLIB$sayHello$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
private static final Method CGLIB$equals$1$Method;
private static final MethodProxy CGLIB$equals$1$Proxy;
private static final Method CGLIB$toString$2$Method;
private static final MethodProxy CGLIB$toString$2$Proxy;
private static final Method CGLIB$hashCode$3$Method;
private static final MethodProxy CGLIB$hashCode$3$Proxy;
private static final Method CGLIB$clone$4$Method;
private static final MethodProxy CGLIB$clone$4$Proxy;

static void CGLIB$STATICHOOK1() {
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
CGLIB$emptyArgs = new Object[0];
Class var0 = Class.forName("dynamic_proxy.p2.HelloConcrete$$EnhancerByCGLIB$$a810359d");
Class var1;
Method[] var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
CGLIB$equals$1$Method = var10000[0];
CGLIB$equals$1$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$1");
CGLIB$toString$2$Method = var10000[1];
CGLIB$toString$2$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$2");
CGLIB$hashCode$3$Method = var10000[2];
CGLIB$hashCode$3$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$3");
CGLIB$clone$4$Method = var10000[3];
CGLIB$clone$4$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$4");
CGLIB$sayHello$0$Method = ReflectUtils.findMethods(new String[]{"sayHello", "(Ljava/lang/String;)Ljava/lang/String;"}, (var1 = Class.forName("dynamic_proxy.p2.HelloConcrete")).getDeclaredMethods())[0];
CGLIB$sayHello$0$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/String;)Ljava/lang/String;", "sayHello", "CGLIB$sayHello$0");
}

final String CGLIB$sayHello$0(String var1) {
return super.sayHello(var1);
}

public final String sayHello(String var1) {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (this.CGLIB$CALLBACK_0 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}

return var10000 != null ? (String)var10000.intercept(this, CGLIB$sayHello$0$Method, new Object[]{var1}, CGLIB$sayHello$0$Proxy) : super.sayHello(var1);
}

final boolean CGLIB$equals$1(Object var1) {
return super.equals(var1);
}

public final boolean equals(Object var1) {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (this.CGLIB$CALLBACK_0 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}

if (var10000 != null) {
Object var2 = var10000.intercept(this, CGLIB$equals$1$Method, new Object[]{var1}, CGLIB$equals$1$Proxy);
return var2 == null ? false : (Boolean)var2;
} else {
return super.equals(var1);
}
}

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

public final String toString() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (this.CGLIB$CALLBACK_0 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}

return var10000 != null ? (String)var10000.intercept(this, CGLIB$toString$2$Method, CGLIB$emptyArgs, CGLIB$toString$2$Proxy) : super.toString();
}

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

public final int hashCode() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (this.CGLIB$CALLBACK_0 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}

if (var10000 != null) {
Object var1 = var10000.intercept(this, CGLIB$hashCode$3$Method, CGLIB$emptyArgs, CGLIB$hashCode$3$Proxy);
return var1 == null ? 0 : ((Number)var1).intValue();
} else {
return super.hashCode();
}
}

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

protected final Object clone() throws CloneNotSupportedException {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (this.CGLIB$CALLBACK_0 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}

return var10000 != null ? var10000.intercept(this, CGLIB$clone$4$Method, CGLIB$emptyArgs, CGLIB$clone$4$Proxy) : super.clone();
}

public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
String var10000 = var0.toString();
switch(var10000.hashCode()) {
case -1816210712:
if (var10000.equals("sayHello(Ljava/lang/String;)Ljava/lang/String;")) {
return CGLIB$sayHello$0$Proxy;
}
break;
case -508378822:
if (var10000.equals("clone()Ljava/lang/Object;")) {
return CGLIB$clone$4$Proxy;
}
break;
case 1826985398:
if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
return CGLIB$equals$1$Proxy;
}
break;
case 1913648695:
if (var10000.equals("toString()Ljava/lang/String;")) {
return CGLIB$toString$2$Proxy;
}
break;
case 1984935277:
if (var10000.equals("hashCode()I")) {
return CGLIB$hashCode$3$Proxy;
}
}

return null;
}

public HelloConcrete$$EnhancerByCGLIB$$a810359d() {
CGLIB$BIND_CALLBACKS(this);
}

public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
CGLIB$THREAD_CALLBACKS.set(var0);
}

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

private static final void CGLIB$BIND_CALLBACKS(Object var0) {
HelloConcrete$$EnhancerByCGLIB$$a810359d var1 = (HelloConcrete$$EnhancerByCGLIB$$a810359d)var0;
if (!var1.CGLIB$BOUND) {
var1.CGLIB$BOUND = true;
Object var10000 = CGLIB$THREAD_CALLBACKS.get();
if (var10000 == null) {
var10000 = CGLIB$STATIC_CALLBACKS;
if (CGLIB$STATIC_CALLBACKS == null) {
return;
}
}

var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
}

}

public Object newInstance(Callback[] var1) {
CGLIB$SET_THREAD_CALLBACKS(var1);
HelloConcrete$$EnhancerByCGLIB$$a810359d var10000 = new HelloConcrete$$EnhancerByCGLIB$$a810359d();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
}

public Object newInstance(Callback var1) {
CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});
HelloConcrete$$EnhancerByCGLIB$$a810359d var10000 = new HelloConcrete$$EnhancerByCGLIB$$a810359d();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
}

public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
CGLIB$SET_THREAD_CALLBACKS(var3);
HelloConcrete$$EnhancerByCGLIB$$a810359d var10000 = new HelloConcrete$$EnhancerByCGLIB$$a810359d;
switch(var1.length) {
case 0:
var10000.<init>();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
default:
throw new IllegalArgumentException("Constructor not found");
}
}

public Callback getCallback(int var1) {
CGLIB$BIND_CALLBACKS(this);
MethodInterceptor var10000;
switch(var1) {
case 0:
var10000 = this.CGLIB$CALLBACK_0;
break;
default:
var10000 = null;
}

return var10000;
}

public void setCallback(int var1, Callback var2) {
switch(var1) {
case 0:
this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2;
default:
}
}

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

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

static {
CGLIB$STATICHOOK1();
}
}

我们看到HelloConcrete$$EnhancerByCGLIB$$a810359d是CGLIB代理之后的对象类型,父类是HelloConcrete,同时实现了net.sf.cglib.proxy.Factory接口,这个接口是CGLIB自己加入的,包含一些工具方法。

我们重点来看一下经过代理生成的sayHello方法:

1
2
3
4
5
6
7
8
9
public final String sayHello(String var1) {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (this.CGLIB$CALLBACK_0 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}

return var10000 != null ? (String)var10000.intercept(this, CGLIB$sayHello$0$Method, new Object[]{var1}, CGLIB$sayHello$0$Proxy) : super.sayHello(var1);
}

其中var10000是我们在代理定义时绑定的MethodInterceptor——MyMethodInterceptor。如果这个interceptor不为null,则调用它的intercept方法;否则调用父类的sayHello方法。

我们知道final类型不能有子类,所以CGLIB不能代理final类型,遇到这种情况会抛出异常。同样的,final方法也是不能重载的,所以也不能通过CGLIB代理,遇到这种情况不会抛出异常,而是会跳过final方法只代理其他方法,即遇到这个方法直接调用父类的方法。

参考资料:

http://rejoy.iteye.com/blog/1627405

http://paddy-w.iteye.com/blog/841798

http://www.importnew.com/27772.html

http://ifeve.com/jdk%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E4%BB%A3%E7%90%86%E4%B8%8Ecglib%E4%BB%A3%E7%90%86%E5%8E%9F%E7%90%86%E6%8E%A2%E7%A9%B6/