Динамический прокси: как обрабатывать вложенные вызовы методов

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

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

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

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

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

2 ответа

Решение

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

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

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

Это потому, что из вашего тестового кода вы звоните 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)и получить ожидаемый результат.

Другие вопросы по тегам