Как использовать АОП для перехвата вызова метода в супер по аргументу?

Я расширяю класс и переопределяю метод. Все, что я хочу сделать, это вызвать 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 это интерфейс, вы можете рассмотреть возможность использования динамического прокси, который бы:

  1. Завернуть оригинал
  2. Перехватить все сообщения и переслать их в исходный каталог

В приведенной выше ссылке есть полный пример. Вот только идея:

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так что если супер использует

  1. отражение
  2. instanceof
  3. или получить доступ к переменным экземпляра напрямую (не используя getter / setter)

, тогда это может быть проблематично.

Надеюсь, что я правильно понял вашу проблему и что она помогает.

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