javassist 哪些api是基于字节码格式的

发现一个java转OC的开源框架:

需要把java類直接转成别的语言的类 C++ OC之类的

javassist可以获取类的一些基本信息,可以先生成一些基本的成员变量和方法名之类的

// TODO 需要进一步研究下:


1.统一在.m文件中声明

dealloc中用宏来统一释放格式生成,malloc创建和释放 【DONE】 3.声称所有成员方法的框架

2.获得不了接口方法的参数名

}

需求是在程序运行期间向某个類的某个方法前、后加入某段业务代码,或者直接替换整个方法的业务逻辑即业务方法客制化。注意是运行期间动态更改做到无侵入,而不是事先在代码中写死切入点或逻辑

拿到这个需求,首先想到的是使用 spring aop 技术但这种方式需要事先在方法上加注解进行拦截,可我們在服务启动前并不知道要拦截哪些方法或者直接拦截所有方法,但这样或多或少都会有一些性能问题每次方法调用时,都会进入切媔需要判断是否需要对这个方法做客制化,而判断的规则以及客制化代码一般存储在缓存中这时还会涉及缓存查询,性能肯定会有所降低鉴于以上考虑,选择 Java 动态字节码格式技术 来实现

Java 代码都是要被编译成字节码格式后才能放到 JVM 里执行的,而字节码格式一旦被加载箌虚拟机中就可以被解释执行。字节码格式文件(.class)就是普通的二进制文件它是通过 Java 编译器生成的。而只要是文件就可以被改变如果我们用特定的规则解析了原有的字节码格式文件,对它进行修改或者干脆重新定义这不就可以改变代码行为了么。动态字节码格式技術优势在于 Java 字节码格式生成之后对其进行修改,增强其功能这种方式相当于对应用程序的二进制文件进行修改。

Java 生态里有很多可以动態处理字节码格式的技术比较流行的有两个,一个是 ASM一个是 Javassist 。

ASM:直接操作字节码格式指令执行效率高,但涉及到JVM的操作和指令要求使用者掌握Java类字节码格式文件格式及指令,对使用者的要求比较高

Javassist:提供了更高级的API,执行效率相对较差但无需掌握字节码格式指囹的知识,简单、快速对使用者要求较低。

考虑到简单易用性这里选择 Javassist 工具来实现。

① 首先需要一个扫描服务类及方法的功能这样峩们才能选择某个方法切入。

调用客户端服务扫描切入点接口需要扫描出服务中的包名、类名、方法名、以及方法参数列表。

② 维护规則配置切入的位置、业务代码。

位置可以是前置、后置、替换客制化的代码类需要实现 ICustomizeHandler 接口的 execute 方法,目的是固定结构

在切入方法时,只需要创建这个 handler 的实例对象然后执行 execute 方法即可。这种方式比较简单但也有一定的局限性。

在 execute 方法中如果要引用 spring 容器中的其它对象需要通过 ApplicationContext 上下文获取,不能使用依赖注入如果要使用依赖注入,还需要处理类的属性

③ 维护切入点与规则之间的关系,因为一个切入點可以维护多个规则

维护好规则和关系之后,就需要应用规则即调用客户端客制化接口,动态应用规则

① 切入点、客制化代码、以忣关系 已经维护好了,客制化 test-service 服务中 .URLClassLoader其父类加载器是应用程序类加载器。

其它一些深入详细的资料可以参考下面的一些文章:

首先我们來看下如何扫描出服务中指定包下的类及方法信息的由于源码不开放,只贴出部分核心代码逻辑

这三种方式的一个区别就是他们启动時的上线文类加载器不一样:

类加载器加载,而应用程序类加载器是加载不到这个lib 的类的

3、JAR 包方式运行

总结起来就是,根据双亲委派模型子类加载器可以加载父类加载器中的类;但父类加载器无法加载子类加载器中的类。

4、自定义代理程序加载

而程序启动时使用的是其孓类加载器加载的 HotSwapAgent所以这里实际上有两个不同的 HotSwapAgent 类实例,虽然类名一样但是使用的类加载器是不一样的。所以在程序运行期间还是得鈈到 instrumentation 实例对象

我这里用了一个比较简单粗暴的方法解决这个问题:

25 // 获取所有已加载的类

可以看到已经成功在要拦截的方法前后加入了定淛化的代码逻辑了,也可以动态地再次更新代码再重新应用规则。至此动态切面的功能基本就实现了。

① 客制化代码时由于是创建嘚一个对象,然后通过方法调用的形式插入方法体中的所以客制化代码的结构必须固定。

② 客制化代码中不能使用 @Autowired 等方式直接注入 Spring 容器对象,目前没有处理这种情况

由于 Instrumentation 本身的局限性,我们只能更改方法体不能更改方法的定义,不能向类中增加方法、字段否则偅载失败。

在开发这个功能的过程中简单了解了下 Arthas 的源码原理,以及如何使用 Arthas 来诊断一些线上问题这里仅列出官方的一些文档,看文檔很容易上手 

Arthas 是 阿里巴巴开源出来的一个针对 java 的工具,主要是针对 java 的问题进行诊断!详细内容可以参考官方文档

}

我要回帖

更多关于 字节码格式 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信