2010-04-15 49 views
2

我在擴展一個類並覆蓋一個方法。我想要做的就是調用super,但是修改後的參數在被調用時被攔截。一個例子使其更加清晰:如何使用AOP在超級參數中攔截方法調用?

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

我寧願使用一個不需要自己編譯器的工具。最理想的是什麼?

回答

3

鑑於Foo是一個接口,你可以考慮使用一個dynamic proxy那會:

  1. 裹原富
  2. 攔截所有消息,並將其轉發到原來的富

有在上面的鏈接中是完整的example。這裏只是想法:

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去)

,那麼它可能有問題。

希望我明白你的問題是正確的,它有幫助。

+0

就是這樣。我在想方式太難的解決方案。感謝您將我帶回地面。 – hleinone 2010-04-15 16:10:59