cglib如何代理增强
cglib是⼀种动态代理技术,可以针对类来⽣成⼀个代理对象。
public class UserService {
public void test(){
System.out.println("test");
}
}
现在利⽤cglib对UserService类中的test()⽅法进⾏增强:
public class Main {
public static void main(String[] args) {
final UserService target = new UserService();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[]
objects, MethodProxy methodProxy) throws Throwable {
// test⽅法增加了其他逻辑
if (method.getName().equals("test")) {
System.out.println("before...");
Object result = method.invoke(target, objects);
System.out.println("after...");
return result;
}
// 其他⽅法正常执⾏
return method.invoke(target, objects);
}
}});
UserService userService = (UserService) enhancer.create();
userService.test();
}
}
cglib能否代理接⼝
定义⼀个UserInterface接⼝:
public interface UserInterface {
public void test();
}
接下来利⽤cglib来代理⼀个接⼝
public class Main {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserInterface.class);
enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[]
objects, MethodProxy methodProxy) throws Throwable {
if (method.getName().equals("test")) {
System.out.println("切⾯逻辑...");
}
return null;
}
}});
UserInterface userInterface = (UserInterface) enhancer.create();
userInterface.test();
}
}
可以正常运⾏的
cglib代理⼀个类和代理⼀个接⼝的底层有什么区别呢
我们可以通过设置
-Dcglib.debugLocation=D:\personal\base\cglib\cglib\target\classes
cglib就会将⽣成的代理类放到上⾯所指定的路径上。那么我们分别来看看cglib代理类和接⼝时所产⽣的代理类。
UserService的代理类
public class UserService$$EnhancerByCGLIB$$4d890297 extends UserService implements Factory {
final void CGLIB$test$0() {
super.test();
}
public final void test() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
var10000.intercept(this, CGLIB$test$0$Method, CGLIB$emptyArgs, CGLIB$test$0$Proxy);
} else {
super.test();
}
}
}
UserInterface的代理类
public class UserInterface$$EnhancerByCGLIB$$20ecfdd extends UserService implements Factory {
final void CGLIB$test$2() {
super.test();
}
public final void test() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
var10000.intercept(this, CGLIB$test$2$Method, CGLIB$emptyArgs, CGLIB$test$2$Proxy);
} else {
super.test();
}
}
}
可以发现类区别不⼤UserService代理类是UserService的⼦类,UserInterface代理类实现了UserInterface。
以UserService代理类举例
test()⽅法内会去调⽤所设置的Callbacks中的intercept(),相当于执⾏增强逻辑,如果没有Callbacks,则会执⾏super.test(),那么我们⾃然能想到,如果不设置Callbacks,那是不是就能正常执⾏?
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
UserService userService = (UserService) enhancer.create();
userService.test();
运⾏这上述段代码时,cglib在构造代理对象时就会报⼀个没有Callbacks的空指针异常
查看代理类中的
final void CGLIB$test$0() {
super.test();
}
这个⽅法我们并不能直接调⽤,要通过所设置的Callback,也就是MethodInterceptor中的MethodProxy对象来调⽤,MethodProxy对象表示⽅法代理,举例,假如UserService代理对象在执⾏test()⽅法,那么当执⾏流程进⼊到intercept()⽅法时,MethodProxy对象表示的就是test()⽅法,但是我们现在知道了在UserService类和UserService代理类中都有test()⽅法,所以MethodProxy对象代理的就是这两个test()
// o表示当前代理对象,target表示被代理对象
// 执⾏UserService代理对象的CGLIB$test$0()⽅法,也就是执⾏UserService代理对象的⽗类的test()
Object result = methodProxy.invokeSuper(o, objects);
// 执⾏UserService对象的CGLIB$test$0()⽅法,会报错,调⽤invokerSuper只能传⼊代理对象
Object result = methodProxy.invokeSuper(target, objects);
// 执⾏UserService对象的test()
Object result = methodProxy.invoke(target, objects);
// 执⾏UserService代理对象的test(); ⼜会进到拦截器,栈溢出
Object result = methodProxy.invoke(o, objects);
执⾏methodProxy.invokeSuper()⽅法时,就会去执⾏CGLIB$test
0
(
)
⽅法。因此
c
g
l
i
b
的⼤概⼯作原理是:
c
g
l
i
b
会根据所设置的
S
u
p
e
r
c
l
a
s
s
,⽣成代理类作为其⼦类,并且会重写
S
u
p
e
r
c
l
a
s
s
中的⽅法,
S
u
p
e
r
c
l
a
s
s
中的某⼀个⽅法,⽐如
t
e
s
t
(
)
,相应的在代理类中会对应两个⽅法,⼀个是重写的
t
e
s
t
(
)
,⽤来执⾏增强逻辑,⼀个是
C
G
L
I
B
0()⽅法。 因此cglib的⼤概⼯作原理是: cglib会根据所设置的Superclass,⽣成代理类作为其⼦类,并且会重写Superclass中的⽅法,Superclass中的某⼀个⽅法,⽐如test(),相应的在代理类中会对应两个⽅法,⼀个是重写的test(),⽤来执⾏增强逻辑,⼀个是CGLIB
0
(
)
⽅
法。因此
c
g
l
ib
的
⼤
概
⼯
作原理是:
c
g
l
ib
会根据所设置的
S
u
p
erc
l
a
ss
,
⽣
成代理类作为其
⼦
类,并且会重写
S
u
p
erc
l
a
ss
中的
⽅
法,
S
u
p
erc
l
a
ss
中的某
⼀
个
⽅
法,
⽐
如
t
es
t
(
)
,相应的在代理类中会对应两个
⽅
法,
⼀
个是重写的
t
es
t
(
)
,
⽤
来执
⾏
增强逻辑,
⼀
个是
CG
L
I
B
test$0(),会直接调⽤super.test(),是让MethodProxy对象来⽤的。
cglib代理类是怎么⽣成的
查看完整代码:
public class UserService$$EnhancerByCGLIB$$4d890297 extends UserService 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$test$0$Method;
private static final MethodProxy CGLIB$test$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("com.zhouyu.UserService$$EnhancerByCGLIB$$4d890297");
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$test$0$Method = ReflectUtils.findMethods(new String[]{"test", "()V"}, (var1 = Class.forName("com.zhouyu.UserService")).getDeclaredMethods())[0];
CGLIB$test$0$Proxy = MethodProxy.create(var1, var0, "()V", "test", "CGLIB$test$0");
}
final void CGLIB$test$0() {
super.test();
}
public final void test() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
var10000.intercept(this, CGLIB$test$0$Method, CGLIB$emptyArgs, CGLIB$test$0$Proxy);
} else {
super.test();
}
}
final boolean CGLIB$equals$1(Object var1) {
return super.equals(var1);
}
public final boolean equals(Object var1) {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == 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 (var10000 == 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 (var10000 == 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 (var10000 == 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 -1422510685:
if (var10000.equals("test()V")) {
return CGLIB$test$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 UserService$$EnhancerByCGLIB$$4d890297() {
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) {
UserService$$EnhancerByCGLIB$$4d890297 var1 = (UserService$$EnhancerByCGLIB$$4d890297)var0;
if (!var1.CGLIB$BOUND) {
var1.CGLIB$BOUND = true;
Object var10000 = CGLIB$THREAD_CALLBACKS.get();
if (var10000 == null) {
var10000 = CGLIB$STATIC_CALLBACKS;
if (var10000 == null) {
return;
}
}
var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
}
}
public Object newInstance(Callback[] var1) {
CGLIB$SET_THREAD_CALLBACKS(var1);
UserService$$EnhancerByCGLIB$$4d890297 var10000 = new UserService$$EnhancerByCGLIB$$4d890297();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
}
public Object newInstance(Callback var1) {
CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});
UserService$$EnhancerByCGLIB$$4d890297 var10000 = new UserService$$EnhancerByCGLIB$$4d890297();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
}
public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
CGLIB$SET_THREAD_CALLBACKS(var3);
UserService$$EnhancerByCGLIB$$4d890297 var10000 = new UserService$$EnhancerByCGLIB$$4d890297;
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();
}
}
发现newInstance()⽅法会重新⽣成⼀个代理对象,setCallbacks()和getCallbacks()可以⽤来设置或获取增强逻辑。
不仅只有test()⽅法会⽣成对应的两个⽅法,其他⽅法也会⽣成,⽐如:equals() toString()hashCode() clone()
代理类中有⼀个代理块,会调⽤CGLIB
S
T
A
T
I
C
H
O
O
K
1
(
)
,这个⽅法主要就是给属性赋值,构造⼀个
T
h
r
e
a
d
L
o
c
a
l
对象给
C
G
L
I
B
STATICHOOK1(),这个⽅法主要就是给属性赋值, 构造⼀个ThreadLocal对象给CGLIB
ST
A
T
I
C
H
OO
K
1
(
)
,这个
⽅
法主要就是给属性赋值,构造
⼀
个
T
h
re
a
d
L
oc
a
l
对象给
CG
L
I
B
THREAD_CALLBACKS属性
获取UserService类中的test⽅法的Method对象给CGLIB$test
0
0
0
Method属性
构造test()⽅法所对应的MethodProxy对象给CGLIB$test
0
0
0
Proxy属性 等
有⼀个⽅法是cglib在⽣成代理对象后,会主动调⽤的⼀个⽅法,这个⽅法是CGLIB$SET_THREAD_CALLBACKS
- cglib⽣成代理类
- 然后调⽤构造⽅法得到代理对象
-
然后cglib调⽤代理对象的CGLIB
SE
T
T
H
R
E
A
D
C
A
L
L
B
A
C
K
S
(
)
⽅法,所设置的
C
a
l
l
b
a
c
k
s
设置到
C
G
L
I
B
SET_THREAD_CALLBACKS()⽅法,所设置的Callbacks设置到CGLIB
SE
T
T
H
RE
A
D
C
A
LL
B
A
C
K
S
(
)
⽅
法,所设置的
C
a
ll
ba
c
k
s
设置到
CG
L
I
B
THREAD_CALLBACKS这个ThreadLocal中 -
后续代理对象在执⾏test()⽅法时,就会从CGLIB$THREAD_CALLBACKS拿到所设置的Callbacks,调⽤其intercept()⽅法
代理类的⽣成逻辑就是: - ⽣成类的定义,实现UserService和Factory接⼝
- 根据UserService类中的⽅法⽣成代理类中对应的⽅法和属性
- ⽣成⼀些辅助的属性和⽅法
MethodProxy是怎么实现的
MethodProxy对象,表示⼀个⽅法的代理,⽐如UserSerivce中的test()⽅法,在对应的代理类中会有对应的两个⽅法:
final void CGLIB$test$0() {
super.test();
}
public final void test() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
var10000.intercept(this, CGLIB$test$0$Method, CGLIB$emptyArgs, CGLIB$test$0$Proxy);
} else {
super.test();
}
}
MethodProxy对象代理就是这两个⽅法
// 表示执⾏某个对象的CGLIB$test$0()⽅法,如果o中没有CGLIB$test$0()⽅法则会报错
methodProxy.invokeSuper(o, args)
// 表示执⾏某个对象的test⽅法
methodProxy.invoke(o, args)
MethodProxy对象的创建,创建的⼊⼝在代理类中:
CGLIB$test$0$Proxy = MethodProxy.create(var1, var0, "()V", "test","CGLIB$test$0");
public static MethodProxy create(Class c1, Class c2, String desc, String name1, String name2) {
// c1是UserService
// c2是UserService代理类
// desc被代理方法的返回值类型
// name1是被代理方法名比如test
// name2是代理类中的CGLIB$test$0方法,会调用super.test()
MethodProxy proxy = new MethodProxy();
proxy.sig1 = new Signature(name1, desc); // 被代理方法签名,也就是代表void test()
proxy.sig2 = new Signature(name2, desc); // 代理方法签名,也就是void CGLIB$test$0()
proxy.createInfo = new CreateInfo(c1, c2); // CreateInfo中表示的就是被代理类和代理类的信息
return proxy;
}
MethodProxy对象中主要有三个属性:
- sig1,表示test⽅法
- sig2,表示CGLIB$test$0⽅法
- createInfo,表示UserService类和UserService代理类
MethodProxy的invoke()和invokeSuper()⽅法:
public Object invoke(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
// f1表示被代理类的FastClass代理类,i1表示被代理方法的下标,这里就是去执行test()方法,具体执行的是哪个对象就看obj
return fci.f1.invoke(fci.i1, obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (IllegalArgumentException e) {
if (fastClassInfo.i1 < 0)
throw new IllegalArgumentException("Protected method: " + sig1);
throw e;
}
}
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
// f2表示UserService代理类的FastClass代理类,i2表示代理方法的下标,这里就是去执行CGLIB$test$0方法,具体执行的是哪个对象就看obj
return fci.f2.invoke(fci.i2, obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
⾸先都需要⽤到⼀个FastClassInfo对象,这个对象是在init()⽅法构造的。
private void init()
{
if (fastClassInfo == null)
{
synchronized (initLock)
{
if (fastClassInfo == null)
{
// CreateInfo中存储了代理类和被代理类
CreateInfo ci = createInfo;
FastClassInfo fci = new FastClassInfo();
fci.f1 = helper(ci, ci.c1); // 被代理类的FastClass代理类,也就是UserService$$FastClass...
fci.f2 = helper(ci, ci.c2); // 代理类的FastClass代理类,也就是UserService$$EnhancerBy...$$FastClasss...
// 被代理方法签名,也就是代表void test()
// 代理方法签名,也就是void CGLIB$test$0()
// 预先生成每个方法所对应的下标,调用时就可以直接利用下标找到方法了,性能高
fci.i1 = fci.f1.getIndex(sig1); // 获取方法签名sig1在被代理类的FastClass代理类中的下标,后续根据下标找到对应的方法,sig1表示被代理方法test()
fci.i2 = fci.f2.getIndex(sig2); // 获取方法签名sigsig2在代理类的FastClass代理类中的下标,后续根据下标找到对应的方法,sig2表示代理方法CGLIB$test$0()
fastClassInfo = fci;
createInfo = null;
}
}
}
}
FastClassInfo对象中主要有四个属性:
- f1,UserService类对应的⼀个FastClass代理对象
- f2,UserService代理类对应的⼀个FastClass代理对象
- i1,test⽅法在UserService类对应的⼀个FastClass代理对象中的下标
- i2,CGLIB$test$0⽅法在UserService代理对对应的⼀个FastClass代理对象
两个类类似,都是针对某⼀个类的FastClass代理类,所以我们好好看⼀下UserService所对应的FastClass,该类主要有:
- ⼀个构造⽅法
- public int getIndex(Signature var1)
- public int getIndex(String var1, Class[] var2)
- public int getIndex(Class[] var1)
- public Object invoke(int var1, Object var2, Object[] var3)
-
public Object newInstance(int var1, Object[] var2)7. public int getMaxIndex()
FastClass的作⽤是提⾼⽅法的执⾏速度,按照正常的实现,当我们调⽤MethodProxy对象的invoke()或invokeSuper()⽅法时,⾸先应该要做到的就是找到对应的Method对象,⽐如:1. 执⾏invoke(),要找到test⽅法对应的Method对象2. 执⾏invokeSuper(),要找到CGLIB$test$0()⽅法对应的Method对象然后利⽤反射来执⾏Method。
然而FastClass的机制就是预先把UserService类或UserService代理类中的所有⽅法做⼀个索引
public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
UserService var10000 = (UserService)var2;
int var10001 = var1;
try {
switch(var10001) {
case 0:
var10000.test();
return null;
case 1:
return new Boolean(var10000.equals(var3[0]));
case 2:
return var10000.toString();
case 3:
return new Integer(var10000.hashCode());
}
} catch (Throwable var4) {
throw new InvocationTargetException(var4);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
调了这个⽅法,就会得到当前要执⾏的⽅法所对应的index
init方法 两个helper()⽅法就是分别去⽣成UserService类和UserService代理类所对应的FastClass代理类。接下来的两个getIndex(),就是分别去:
- 去UserService类对应的FastClass代理类中找到test()⽅法的下标i1
- 去UserService代理类对应的FastClass代理类中找到CGLIB$test$0()⽅法的下标i2然后把两个下标都记录在fastClassInfo中。
- invoke:fci.f1.invoke(fci.i1, obj, args),执⾏UserService类对应的FastClass代理类的invoke⽅法
-
invokeSuper:fci.f2.invoke(fci.i2, obj, args),执⾏UserService代理类对应的FastClass代理类的invoke⽅如
⽐如下标为0,就会执⾏var10000.test();⽽var10000,是所传⼊对象强制转化为4d890297类的对象,4d890297其实就是UserService的代理类。所以我们可以发现,当执⾏invokeSuper()这个⽅法时,不能传⼊UserService对象,只能传⼊UserService的代理对象,不然就不能转换成为UserService代理类类型。
因此FastClass,快的地⽅就是预先把⽅法信息都⽣成好了,在真正调⽤的时候,不⽤再去找Method对象,⽽是直接就执⾏⽅法了