la manipulación de código de bytes de intercepción estableciendo el valor de un campo
-
11-10-2019 - |
Pregunta
El uso de una biblioteca como ASM
o cglib
, ¿hay una manera de añadir instrucciones de código de bytes a una clase para ejecutar código cada vez que se establece el valor de un campo de clase?
Por ejemplo, digamos que tengo esta clase:
public class Person
{
bool dirty;
public String name;
public Date birthDate;
public double salary;
}
Supongamos que una sección de código contiene esta línea:
person.name = "Joe";
Quiero esta instrucción a ser interceptada por lo que el indicador se establece en dirty
true
. Sé que esto es posible que los métodos setter - person.setName (“Joe”)
- como los métodos de clases pueden ser modificados por la manipulación de código de bytes, pero quiero hacer lo mismo para un campo
¿Es esto posible, y si es así, ¿Cómo
Editar
Quiero evitar modificar la sección de código que tiene acceso a la clase, estoy buscando una manera de mantener el código de intercepción como parte de la clase Person
. ¿Hay un pseudo-métodos para el acceso de campo, similares a las propiedades de las clases de Python?
Solución
Existen dos códigos de bytes para los campos de actualización: putfield
y putstatic
(ver http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc11.html ). Estos se pueden encontrar en el código de la clase usando, así que no hay manera de modificar simplemente Person
.
Otros consejos
En resumen, es necesario inyectar código de bytes que hace lo siguiente en el método de interés:
if (person.name.equals("Joe") {
dirty = true;
}
No se puede evaluar el campo durante la instrumentación - que tiene que ser en tiempo de ejecución cuando el método se ejecuta ??p>.
En cuanto a su pregunta de cómo, intente lo siguiente:
- Escribir el código en una clase de prueba y generar una versión ASCII del código de bytes para ver lo que se ha generado. Esto se puede hacer fácilmente con
javap
.