33

我知道 Javassist 是一个 Java 库,它提供了一种操作应用程序的 Java 字节码的方法。

好的,但是为什么我们需要操纵字节码呢?

有什么真实的例子吗?任何真正的应用程序,javassist 在哪里使用?

4

4 回答 4

39

一个常见的应用是在运行时生成代理类,即在运行时创建一个子类来拦截所有的方法调用。例子:

Hibernate使用代理来拦截实体上的方法调用以实现延迟加载,即在第一次访问时从数据库中获取对象。

Spring Framework 使用代理来实现其 AOP 支持,其中包括支持声明式事务。它还使用代理来强制执行适当的范围界定。

EJB使用代理来实现容器管理的事务、授权检查以及应用用户定义的拦截器。

CDI实现还必须代理托管 bean 以确保正确的范围。我怀疑他们也使用字节码工程库。

最近使用 Javassist 实现了方法返回值的透明缓存,通过拦截所有方法调用并仅在第一次调用时委托给超级实现。

注意java.lang.reflect.Proxy可以在运行时生成代理类,但只能实现接口,不能扩展类。上述所有用例都需要代理类。

于 2011-09-04T07:02:58.637 回答
16

字节码操作是有用且必要的,尤其是当您没有某些项目的源代码时。假设您只有某个项目的字节码(如 jar 文件),但您想以某种方式更改代码的行为,字节码操作库可以在这种情况下提供帮助。字节码操作的好处是你不需要重新编译你的代码,操作后可以直接执行。

我已经使用字节码操作来进行一些程序分析。给定一个库,我想知道在运行时调用了库中的哪些方法。我可以使用字节码操作System.out.println("method_name");在方法的开头插入一条语句。所以在运行时,它会打印出调用了哪些方法。

一些字节码操作库是:

于 2011-09-04T05:42:37.643 回答
1

扩展 Meriton 的答案并提供一个真实的使用示例:

Hibernate-core (5.2.8.Final) 使用 javaassit (3.20.0-GA):

https://mvnrepository.com/artifact/org.hibernate/hibernate-core/5.2.8.Final

于 2017-03-10T18:59:45.830 回答
0

ASM 项目的用户页面列出了几十个使用 ASM 进行字节码分析和操作的广泛使用的 Java 项目和框架。http://asm.ow2.org/users.html

于 2011-09-04T11:40:21.233 回答