CGLIB代理方法执行基本流程
拦截器的intercept调用的秘密
一般我们在这里面做一些增强,然后调用原来的对象的方法,也就是methodProxy.invokeSuper
,但是前面说了,传入参数o
是代理对象,他是怎么调用原来的对象呢。:
MethodProxy的invokeSuper调用父类方法
其实看这个名字就知道是调用原方法,调用父类方法嘛,前面有继承嘛,对吧。但是事实是怎么样呢,我们来看看吧:
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
init();//初始化fastClassInfo
FastClassInfo fci = fastClassInfo;
return fci.f2.invoke(fci.i2, obj, args);
}
catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
MethodProxy的init创建FastClassInfo
FastClassInfo
这个类其实就是存放了两个FastClass
对象,和两个索引,他们是什么,其实就是两个FastClass
增强对象,和锁对应方法的索引。索引什么鬼,简单的说吧,JDK
反射调用方法有很多检查,性能肯定有损耗,所以CGLIB
就想能不能我再创建两个类,一个是有原方法的类,一个是代理方法的类,里面有很多方法对应的索引,如果我能获取一个方法的索引,根据索引可以调用对应类的方法,这样避免用反射调用,具体做法我后面会分析,现在知道个大概就好。
动态生成FastClass增强类
这里就是根据创建的信息CreateInfo
,来创建被代理类和代理类的FastClass
增强对象,而且是动态创建的,还用了双重检测,只会创建一次。
private void init() {
if (fastClassInfo == null) {
synchronized (initLock) {
if (fastClassInfo == null) {
CreateInfo ci = createInfo;
FastClassInfo fci = new FastClassInfo();
fci.f1 = helper(ci, ci.c1);
fci.f2 = helper(ci, ci.c2);
fci.i1 = fci.f1.getIndex(sig1);
fci.i2 = fci.f2.getIndex(sig2);
fastClassInfo = fci;
createInfo = null;
}
}
}
}
此时我们看到两个增强的类,和两个索引,f1,i1
对应的是被代理类的FastClass
增强对象,f2,i2
对应的是代理类的FastClass
增强对象:
而且生成了字节码文件,就是EnhancerByCGLIB
再增强FastClassByCGLIB
,另外一个CglibObj$$FastClassByCGLIB$$2bb5f2d7
是在前面创建代理的时候就创建了,只是前面没讲,现在讲:
这些FastClass
增强类到底增强什么呢,其实是方法的调用,跟索引有关,他会根据方法签名去FastClass
增强类获取相关的索引,因为所有的方法都在FastClass
增强类里:
看到了吧,CglibObj$$FastClassByCGLIB$$2bb5f2d7
里面f1
方法的返回索引是0
,
看到了吧,CglibObj$$EnhancerByCGLIB$$ef630afc$$FastClassByCGLIB$$9f694f5b
里面f1
的方法的返回索引是13
:
这些方法前面字符串哪里来的啊,其实前面有,我就稍微提下:
name
和desc
拼起来的,这些都是生成字节码的时候根据方法生成的:
FastClass
增强对象和方法索引都获取到了:
获取了之后怎么用呢,下篇讲啦。
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。
Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。
它的内容包括:
- 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
- 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
- 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
- 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
- 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
- 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
- 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
- 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw
目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:
想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询
同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。