2011-08-08 5 views
6

estoy trabajando con BeanBinding mucho en mi proyecto actual y por lo que tengo código que se parece a ...¿Convierte un nombre de método en nombre de bean en tiempo de ejecución?

TypeA objA; 
TypeB objB; 
Bindings.createAutoBinding(UpdateStrategy.READ, 
    objA, BeanProperty.create("X"), 
    objB, BeanProperty.create("X")) 
    .bind(); 

Dónde objA y objB son instancias de clases que tienen un método setX(). El problema es que si refactorizo ​​setX a setY, entonces necesito buscar estos nombres de propiedad de cadenas. Me doy cuenta de que puedo crear cadenas finales estáticas para el nombre de la propiedad, pero si logro que el compilador haga el trabajo por mí, mucho mejor.

Idealmente, lo que me gustaría ser capaz de hacer es ...

TypeA obja; 
TypeB objB; 
Bindings.createAutoBinding(UpdateStrategy.READ, 
    objA, BeanProperty.create(Magic.returnBeanName(TypeA.class).getX()), 
    objB, BeanProperty.create(Magic.returnBeanName(TypeB.class).setX()) 
    .bind(); 

Parecería que esto podría ser posible a través de una síntesis y/o aspectos código.

+0

Una toma completa en la oscuridad, pero tal vez 'returnBeanName' puede usar javassist para crear un objeto que tome cada método getter, modifique su tipo de retorno a String y devuelva el nombre de la propiedad? Parece un poco loco, pero suena divertido de escribir. – Jeremy

+0

@Jeremy: Pensé en su sugerencia, pero para que Eclipse y otras herramientas de refactorización funcionen, la firma del método debe permanecer igual, lo que sería un problema real para los incubadores ya que producen vacíos y también métodos finales ya que son "especiales " –

+0

No quise decir que debas modificar el bean en sí. Quise decir que podrías hacer una copia de la clase de bean, con nombres de método exactamente iguales a tu bean, pero con esos métodos devolviendo el nombre de la propiedad. – Jeremy

Respuesta

1

Una toma completa en la oscuridad, pero tal vez returnBeanName puede usar javassist para crear una clase diferente similar al bean, excepto que modifica los tipos de devolución de los getters a String y devuelve el nombre de la propiedad?

Por ejemplo, si el bean tiene el siguiente aspecto:

public class Foo{ 
    private int x; 

    public int getX(){ 
     return x; 
    } 

    public void setX(int x){ 
     this.x= x; 
    } 
} 

A continuación, crear dinámicamente una clase diferente que tiene este aspecto:

public class FooMeta{ 
    public String getX(){ 
     return "x"; 
    } 
} 

parecer un poco loco, pero suena divertido escribir.

+0

Janino podría ser una buena opción aquí –

+0

Nvm, janino es el tiempo de ejecución solamente –

0

Puede usar instrumentation: cree un java agent usando ASM para acceder a sus clases en tiempo de compilación y generar las clases/interfaces/métodos necesarios. No es fácil y debes invertir tiempo para aprender sobre la instrumentación de Java, el código de bytes de JVM y la biblioteca de ASM, pero puedes hacer maravillas con ella.

+0

Sí, de hecho sé cómo hacer, pero les viene el problema de que ahora necesito registrar las clases generadas de nuevo para eclipsar para que pueda manejar la refactorización. Una razón por la que esperaba que alguien dijera que ya existía algún plu/lib. –

0

he hecho algo parecido a lo que Jeremy Heiler sugirió en mi proyecto de código abierto, Funcito, que se podía browse the source code para ver un ejemplo de lo que hay que hacer para utilizar la manipulación de código de bytes, utilizando Javassist o CGLIB.

La idea general es que utilice un potenciador de código de Javassist o CGLIB para proxy la clase de interés como una subclase que tiene un interceptor de método. Usted intercepta la llamada al método y registra el nombre del método invocado, y luego gira y extrae el nombre del método invocado y lo usa como lo desee. La semántica para su uso sería muy similar a la semántica de uso de Funcito, que está cerca de lo que publicó como su ideal.

Cuestiones relacionadas