Convert method name to bean name at runtime?

I work with BeanBinding a lot in my current project, and so I have code that looks like ...

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

Where objA and objB are instances of classes that have a setX() method. The problem is that if I reorganize setX into setY , then I need to track down these string property names. I understand that I can create static end lines for the property name, but if I can get the compiler to do the work for me, all the better.

Ideally, I would like to be able to ...

 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(); 

It would seem that this may be possible through some code synthesis and / or aspects.

+6
source share
3 answers

A full snapshot in the dark, but maybe returnBeanName can use javassist to create another class similar to a bean, except that it changes the returned getters to String and returns the property name?

For example, if your bean looks like this:

 public class Foo{ private int x; public int getX(){ return x; } public void setX(int x){ this.x= x; } } 

Then dynamically create another class that looks like this:

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

It seems crazy, but it sounds fun to write.

+1
source

You can use instrumentation : create a java agent using ASM to access your classes at compile time and create the necessary classes / interfaces / methods. It's not easy, and you have to invest time to learn about Java tools, JVM bytecode and ASM library, but you can do wonders with it.

0
source

I did something like what Jeremy Hyler suggested in my open source project, Funcito , which you could look at the source code to see an example of what you need to do to use byte code manipulation using Javassist or CGLIB.

The general idea is that you are using a code amplifier from Javassist or CGLIB for the proxy class of interest as a subclass that has an interceptor method. You intercept a method call and write down the name of the called method, and then go around and retrieve the name of the called method and use it as you see fit. The semantics for your use will be very similar to the semantics of using Funcito, which is close to what you placed as your ideal.

0
source

Source: https://habr.com/ru/post/894564/


All Articles