Javassist进行。 什么是主要想法和实际使用的地方?

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

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

任何真实的例子? 任何真正的应用程序,javassist使用?

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

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

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

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

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

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

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

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

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

一些字节码操作库是:

  • ASM
  • ByteBuddy
  • BCEL

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

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

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

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