字节码操作以拦截设置字段的值
使用像 ASM 或 cglib 这样的库,有没有办法向类添加字节码指令,以便在设置类字段的值时执行代码?
例如,假设我有这个类:
public class Person
{
bool dirty;
public String name;
public Date birthDate;
public double salary;
}
假设一段代码包含这一行:
person.name = "乔";
我希望拦截该指令,因此将 dirty
标志设置为 true
。我知道这对于 setter 方法是可能的 - person.setName (“Joe”)
- 因为类方法可以通过字节码操作进行修改,但我想对 做同样的事情字段。
这可能吗?如果可能的话,如何?
编辑
我想避免修改访问该类的代码部分,我正在寻找一种方法将拦截代码保留为 Person
类的一部分。是否有类似于 Python 类中的属性的字段访问伪方法?
Using a library like ASM
or cglib
, is there a way to add bytecode instructions to a class to execute code whenever the value of a class field is set?
For example, let’s say I have this class:
public class Person
{
bool dirty;
public String name;
public Date birthDate;
public double salary;
}
Let’s say a section of code contains this line:
person.name = "Joe";
I want this instruction to be intercepted so the dirty
flag is set to true
. I know this is possible for setter methods -- person.setName (“Joe”)
-- as class methods can be modified by bytecode manipulation, but I want to do the same thing for a field.
Is this possible, and if so, how?
EDIT
I want to avoid modifying the code section that accesses the class, I'm looking for a way to keep the interception code as part of the Person
class. Are there a pseudo-methods for field access, similar to properties in Python classes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有两种用于更新字段的字节码:
putfield
和putstatic
(请参见 http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc11.html)。这些可以在使用类的代码中找到,因此无法简单地修改Person
。There are two bytecodes for updating fields:
putfield
andputstatic
(see http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc11.html). These will be found in the code for the using class, so there's no way to simply modifyPerson
.简而言之,您需要在感兴趣的方法中注入执行以下操作的字节码:
您无法在检测时评估该字段 - 它必须在方法执行时在运行时评估。
关于如何操作的问题,请尝试以下操作:
javap
轻松完成此操作。In short, you need to inject bytecode that does the following in the method of interest :
You cannot evaluate the field at instrumentation time - it has to be at runtime when the method is executing.
Regarding your question of how, try the following:
javap
.