字节码操作有哪些合法用途以及人们如何在实践中实现这些基于字节码操作的解决方案?
更新:我应该说得更清楚,这个问题实际上是关于人们使用什么模式和技术在字节码操作的帮助下使他们的代码飞起来。
类似于已经提到的面向方面的编程或动态构建代理对象以及类似的技术。
What legitimate uses are there for bytecode manipulation and how people implement those bytecode manipulation based solutions in practice?
Update: I should have made it more clear that this question really is about what patterns and techniques people use to make their code fly with the help of bytecode manipulation.
Something like aspect oriented programming that was already mentioned or building proxy objects on the fly and similar techniques.
发布评论
评论(5)
字节码操作使您可以实现任意复杂(且有趣)的程序转换,例如:
范围是无穷无尽的;这只是一个小样本。
至于通常如何完成此操作,请从此处开始。
Bytecode manipulation lets you implement arbitrarily complex (and interesting) program transformations, such as:
The scope is endless; this is just a small sampling.
As for how this is typically done, start here.
因此,我们可以读取字节码来实现解释器/JVM。在实现 Java 编译器或针对 JVM 的另一种语言的编译器时,可以编写/生成字节码(例如 Scala 和 Jython)。您可以执行字节码操作来优化字节码(如果您想生产和销售字节码优化器,或者需要它作为内部工具以使您公司的代码在竞争中具有优势)。同样,您可能会操纵字节码以便在分发之前对其进行混淆。您还可以对面向方面的编程执行字节码操作;例如,您可能想要插入挂钩(可能是出于计时或日志记录目的或出于某种其他原因),并且操作字节码是否比编辑所有源文件更简单或更便宜(例如,如果源代码不可用或来自许多不同的来源,并非所有来源都在某人的控制之下,或者说服这些团队添加此类挂钩可能既昂贵又耗时),这可能是一种情况将修改插入到最终字节码输出中,而不是尝试修改原始代码(这可能需要上游或维护单独的分支,或从仅提供字节码的第三方购买源代码)。
您可以自己操作字节码,尽管有许多现有的开源库和框架可以做到这一点,包括 BCEL 和ASM 仅举几个例子。
So, one can read bytecode to implement an interpreter / JVM. One can write / generate bytecode when implementing a Java compiler or a compiler for another language that will target the JVM (e.g. Scala and Jython). You might perform bytecode manipulation to optimize bytecode (if you want to produce and market a bytecode optimizer or you need it as an internal tool to give your company's code an edge over the competition). In a similar vein, you might manipulate bytecode in order to obfuscate it prior to distribution. You might also perform bytecode manipulation for aspect-oriented programming; for example, you might want to insert hooks (maybe for timing or logging purposes or for some other reason), and if it were simpler or less expensive to manipulate the bytecode than to edit all the source files (such as might be the case if the source code is unavailable or from many different sources, not all of which may be under one's control or for which it might be expensive and time-consuming to convince those teams to add such hooks), this might be a case where it would make sense to insert the modifications to the final bytecode output rather than to attempt to modify the original code (which might require upstreaming or maintaining a separate fork, or purchasing the source code from a third party that supplies only the bytecode).
You can manipulate bytecode yourself, although there are many existing open source libraries and frameworks to do it, including BCEL and ASM to name just a couple.
有论文面向方面的设计模式 (PDF) 和 面向方面的设计原则:面向对象设计的经验教训 (PDF) 描述了 AOP/字节码操作的一些模式。
就我个人而言,我在 ASM 进行字节码操作/" rel="nofollow noreferrer">一个框架 为使用该框架的类生成一些样板代码。该框架需要客户端代码自定义 equals() 和 hashCode() 方法,因此我 通过挂钩 rel="nofollow noreferrer">Java 代理,它在 ClassLoader 加载类时修改字节码。我也多次使用 CGLIB 来生成动态代理(如果这算作 AOP)。
There are papers Patterns of Aspect-Oriented Design (PDF) and Aspect-Oriented Design Principles: Lessons from Object-Oriented Design (PDF) which describe some patterns for AOP/bytecode manipulation.
Personally I have used bytecode manipulation with ASM in one framework to generate some boilerplate code for classes which use that framework. The framework requires custom equals() and hashCode() methods for client code, so I generate those by hooking in a Java Agent which modifies the bytecode as the ClassLoader loads the classes. I have also many times used CGLIB to produce dynamic proxies (if that counts as AOP).
字节码操作的一种用途是面向方面的编程。在 Java 中,您可以使用 AspectJ 来实现此目的。
One use for bytecode manipulation is in aspect oriented programming. In Java, you can use AspectJ for this.
一些框架,例如 BEA KODO(Java 数据对象规范的实现),使用字节码操作来“增强”普通旧 Java 对象并基于 XML 描述添加持久性逻辑。
因此,然后在字节码上自动生成数据库映射信息。
Some frameworks such as BEA KODO (Implementation of the Java Data Objects specification) use bytecode manipulation to "enhance" Plain Old Java Objects and add the persistence logic, based on an XML description.
Thus, database mapping information is then automatically generated on the bytecode.