Динамический прокси: как обрабатывать вложенные вызовы методов - PullRequest
0 голосов
/ 23 февраля 2012

Я пытаюсь выучить динамические прокси на Java.

Я знаю, как они работают, но я не могу найти решение моей проблемы: учитывая интерфейс и его реализацию с помощью методов a (), b () и c (), вложенных друг в друга (скажем, a () вызывает b (), который вызывает c ()), я бы хотел прокси-объект для записи в журнал КАЖДОГО вызова методов.

Так что я кодирую мой InvocationHandler, такой как метод invoke (), печатает строку журнала перед выполнением.

Но когда я вызываю proxy.a (), регистрируется только вызов метода a (), а не вся цепочка методов.

Чего мне не хватает? Является ли целью прокси сам прокси?

Ответы [ 2 ]

2 голосов
/ 23 февраля 2012

Это потому, что, хотя из вашего тестового кода вы вызываете proxy.a(), ваш последний a() метод вызывает не proxy.b(), а непосредственно для собственного экземпляра b().

В качестве обходного пути вы можете перегрузить каждый метод, передав ему экземпляр делегата. Добавляем имя класса MyClass и имя интерфейса MyInterface:

void a() {
   //to keep the non-proxy working, the default method have to pass the 
   //self intance
   a(this);
}
void a(MyInterface target) {
   target.b(target);
}

void b() {
   b(this);
}
void b(MyInterface target) {
   target.c(target);
}
void c() {
   c(this);
}
void c(MyInterface target) {
   //do whatever
}

Тогда из вашего тестового кода вы сможете позвонить proxy.a(proxy) и получить ожидаемый результат.

2 голосов
/ 23 февраля 2012

Ну, сам объект не знает, что он проксируется, поэтому, когда a () вызывает b (), это будет обычный вызов "внутри объекта".

Если целью прокси является сам прокси, у вас будет цикл.

Один из способов решить эту проблему, если это действительно необходимо, - это ввести делегата в целевой объект и установить его с прокси или с самим собой в качестве делегата. Странно, но может сработать. Остерегайтесь петель.

...