Можно ли использовать cglib для перехвата прямого поля? - PullRequest
2 голосов
/ 19 марта 2012

В следующем тестовом примере прямое поле t не перехватывается CGLIB.Так можно ли использовать CGLIB?

public class Test {

@Test
public void testCGLib() {
    A a = (A) Enhancer.create(A.class, new Class[] {}, new B());
    System.out.println(a.t);
    a.t();
}

public static class A {

    public int t = 0;

    public void t() {
        System.out.println("bbb");
    }

}

public static class B implements LazyLoader {

    @Override
    public Object loadObject() throws Exception {
        System.out.println("xxx");
        return new A();
    }
}
}

1 Ответ

0 голосов
/ 14 ноября 2013

Нет, это невозможно.Доступ к полю не делегирован какому-либо байтовому коду класса, который определяет поле.он напрямую загружается методом, который использует поле.(В вашем случае это Test#testCGLib.)

cglib создает подкласс и перехватывает вызовы методов.Однако поля не могут быть переопределены, они не являются полиморфными, с или без cglib.Следовательно, вы никогда не сможете перехватить доступ к полю.Вы можете скрыть поля только в подклассах.

Но даже если вы скрывали поле A#t в инструментированном классе: поскольку класс cglib не виден во время компиляции, вы не можете ссылаться на поле по инструментальному типу.Если инструментированный класс A$$cglib имеет поле t, вы можете получить к нему доступ только с помощью

a.getClass().getField("x").get(a)

, чтобы эмулировать какое-то динамическое связывание полей.(По сути, методы динамически связаны, что приводит к тому, что поле right выбирается динамически.

...