Преобразовать имя метода в имя компонента во время выполнения? - PullRequest
6 голосов
/ 08 августа 2011

Я много работаю с BeanBinding в моем текущем проекте, поэтому у меня есть код, похожий на ...

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

Где objA и objB - это экземпляры классов, которые имеют метод setX(). Проблема заключается в том, что если я рефакторинг setX в setY, то мне нужно выследить эти имена свойств строки. Я понимаю, что могу создавать статические финальные строки для имени свойства, но если мне удастся заставить компилятор сделать работу за меня, тем лучше.

В идеале я бы хотел иметь возможность ...

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

Казалось бы, это могло бы быть возможно посредством некоторого синтеза кода и / или аспектов.

Ответы [ 3 ]

1 голос
/ 09 августа 2011

Полный выстрел в темноте, но, возможно, returnBeanName может использовать javassist для создания другого класса, похожего на bean-компонент, за исключением того, что он изменяет возвращаемые типы получателей для String и возвращает имя свойства?

Например, если ваш компонент выглядит следующим образом:

public class Foo{
    private int x;

    public int getX(){
        return x;
    }

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

Затем динамически создайте другой класс, который выглядит следующим образом:

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

Кажется, видсумасшедший, но звучит весело писать.

0 голосов
/ 28 февраля 2013

Я сделал что-то вроде того, что Джереми Хейлер предложил в моем проекте с открытым исходным кодом, Funcito , с помощью которого вы могли бы просмотреть исходный код , чтобы увидеть пример того, что нужно сделать, чтобы используйте манипулирование байтовым кодом, используя либо Javassist, либо CGLIB.

Общая идея заключается в том, что вы используете энхансер кода из Javassist или CGLIB, чтобы проксировать интересующий вас класс в качестве подкласса с перехватчиком метода. Вы перехватываете вызов метода и записываете имя вызванного метода, а затем оборачиваетесь, извлекаете имя вызванного метода и используете его по своему усмотрению. Семантика для вашего использования будет очень похожа на семантику использования Funcito, которая близка к тому, что вы объявили своим идеалом.

0 голосов
/ 01 сентября 2011

Вы можете использовать инструментарий : создать Java-агент , используя ASM , чтобы получить доступ к вашим классам во время компиляции и сгенерировать необходимые классы / интерфейсы / методы. Это не легко, и вы должны потратить время на изучение инструментария java, байт-кода JVM и библиотеки ASM, но вы можете творить чудеса с ним.

...