2010-04-15 3 views
2

J'étends une classe et remplace une méthode. Tout ce que je veux faire est d'appeler super, mais avec un argument modifié qui est intercepté sur l'une de ses méthodes est appelé. Un exemple le rend plus clair:Comment utiliser AOP pour intercepter un appel de méthode en super sur un argument?

// 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); 
} 

Je préfère utiliser un outil qui ne nécessite pas de compilateur. Quel serait le meilleur?

Répondre

3

Étant donné que Foo est une interface, vous pouvez envisager d'utiliser un dynamic proxy qui:

  1. Enroulez le foo d'origine
  2. Intercept tout message et les transmettre à la foo originale

Il est un example complet dans le lien ci-dessus. Voici juste l'idée:

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(...); 

Notez que si Foo n'était pas une interface, vous pouvez toujours sous-classe Foo et passer outre toutes les méthodes manuellement afin de les transmettre.

class SubFoo extends Foo 
{ 
    Foo target; 

    SubFoo(Foo target) { this.target = target }; 

    public void method1() { target.method1(); } 

    ... 
} 

C'est du pseudo-code, et je ne l'ai pas testé. Dans les deux cas, l'encapsuleur vous permet d'intercepter un appel au super.

Bien sûr, l'emballage n'a pas la même classe que l'original Foo, donc si super utilise

  1. réflexion
  2. instanceof
  3. ou d'instance d'accès des variables directement (ne passe pas par getter/setter)

, alors il pourrait être problématique.

J'espère que j'ai bien compris votre problème et que cela aide.

+0

C'est ça. Je pensais à une solution trop difficile. Merci de m'avoir ramené au niveau du sol. – hleinone

Questions connexes