Как использовать АОП для перехвата вызова метода в супер по аргументу?
Я расширяю класс и переопределяю метод. Все, что я хочу сделать, это вызвать super, но с измененным аргументом, который перехватывается, вызывается один из его методов. Пример проясняет ситуацию:
// Foo is an interface and also this method is part of an interface
@Override
public void foo(Foo foo) {
// I want to intercept the call to foo.bar() in super
super.foo(foo);
}
Я бы предпочел использовать инструмент, который не требует собственного компилятора. Что будет оптимальным?
1 ответ
При условии Foo
это интерфейс, вы можете рассмотреть возможность использования динамического прокси, который бы:
- Завернуть оригинал
- Перехватить все сообщения и переслать их в исходный каталог
В приведенной выше ссылке есть полный пример. Вот только идея:
public class DebugProxy implements java.lang.reflect.InvocationHandler {
private Object obj;
private DebugProxy(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable
{
System.out.println("before method " + m.getName());
return m.invoke(obj, args);
}
}
Foo original = ... ;
Foo wrapper = (Foo) java.lang.reflect.Proxy.newProxyInstance(
original.getClass().getClassLoader(),
original.getClass().getInterfaces(),
new DebugProxy(original));
wrapper.bar(...);
Обратите внимание, что если Foo
не был интерфейс, вы все еще можете подкласс Foo
и переопределить все методы вручную, чтобы переслать их.
class SubFoo extends Foo
{
Foo target;
SubFoo( Foo target ) { this.target = target };
public void method1() { target.method1(); }
...
}
Это псевдокод, и я его не проверял. В обоих случаях оболочка позволяет перехватить вызов в super
,
Конечно, оболочка имеет не тот же класс, что и оригинал Foo
так что если супер использует
- отражение
instanceof
- или получить доступ к переменным экземпляра напрямую (не используя getter / setter)
, тогда это может быть проблематично.
Надеюсь, что я правильно понял вашу проблему и что она помогает.