设为首页 加入收藏

TOP

浅谈字节码增强技术系列2-Asm与Cglib(四)
2023-07-25 21:38:05 】 浏览:68
Tags:谈字节 强技术 2-Asm Cglib
te static final void CGLIB$BIND_CALLBACKS(Object var0) { Target$$EnhancerByCGLIB$$e7b1b1b0 var1 = (Target$$EnhancerByCGLIB$$e7b1b1b0)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); Target$$EnhancerByCGLIB$$e7b1b1b0 var10000 = new Target$$EnhancerByCGLIB$$e7b1b1b0(); CGLIB$SET_THREAD_CALLBACKS((Callback[])null); return var10000; } public Object newInstance(Callback var1) { CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1}); Target$$EnhancerByCGLIB$$e7b1b1b0 var10000 = new Target$$EnhancerByCGLIB$$e7b1b1b0(); CGLIB$SET_THREAD_CALLBACKS((Callback[])null); return var10000; } public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) { CGLIB$SET_THREAD_CALLBACKS(var3); Target$$EnhancerByCGLIB$$e7b1b1b0 var10000 = new Target$$EnhancerByCGLIB$$e7b1b1b0; 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(); } }

从代理对象反编译源码可以知道,代理对象继承于Target,拦截器调用intercept()方法,intercept()方法由自定义CGLibProxy实现,所以,最后调用CGLibProxy中的intercept()方法,从而完成了由代理对象访问到目标对象的动态代理实现。

1.2.3、jdk代理和cglib代理的总结

JDK动态代理:

. 需要目标类实现接口

. 生成的代理类是与目标类平级,实现了共同的接口

. 使用反射的方式进行最终方法的调用,性能较低

CGLIB动态代理:

. 不要求目标类实现接口

. 生成的代理类是目标类的子类

. final方法不会出现在代理类中

. 使用空间换时间的思想对最终的方法调用进行了优化,提升了运行时性能。

看到这里,大佬们此时是不是心里会产生个疑问:你的标题不是asm与cglib吗,前面说了这么多cglib代理和jdk代理,和asm有关系吗?哈哈,其实虽然我们没有再前面的内容中介绍asm的相关知识,但是其实字里行间都透漏着asm,整体总结一句就是CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。

二、深入ASM

2.1、简介

ASM 是一个 Java 字节码操控框架。它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元数据来解析类中的所有元素:类名称、方法、属性以及 Java 字节码(指令)。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。

与 BCEL 和 SERL 不同,ASM 提供了更为现代的编程模型。对于 ASM 来说,Java class 被描述为一棵树;使用 “Visitor” 模式遍历整个二进制结构;事件驱动的处理方式使得用户只需要关注于对其编程有意义的部分,而不必了解 Java 类文件格式的所有细节:ASM 框架提供了默认的"response taker"处理这一切。(官方文档:https://asm.ow2.io/asm4-guide.pdf * *中文文档: https://cf.jd.com/pages/viewpage.action?pageId=1139356247

流程图

2.2、核心api介绍

ASM框架中的核心类有以下几个:

① ClassReader:该类用来解析编译过的class字节码文件。

② ClassWriter:该类用来重新构建编译后的类,比如说修改类名、属性以及方法,甚至可以生成新的类的字节码文件。

③ ClassAdapter:该类也实现了ClassVisitor接口,它将对它的方法调用委托给另一个ClassVisitor对象。

下面会列举每个核心类的几个核心api供大家参考,后面如果想了解更多的内容,可以直接查看asm的官方文档

首页 上一页 1 2 3 4 5 6 7 下一页 尾页 4/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇新版IDEA无法解析Maven项目无法解.. 下一篇Tomcat工作原理

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目