Динамический прокси: как обрабатывать вложенные вызовы методов
Я пытаюсь изучить динамические прокси в 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)
и получить ожидаемый результат.