2010-09-02 8 views
5

Hier ist eine Frage: Ich habe Methode digest(byte[] data). Es sollte privat sein, weil wir es außerhalb einer Klasse wirklich nicht brauchen, aber ich werde nicht sterben, wenn ich es öffentlich mache, wenn es hilft.
Die Frage ist: kann ich Abfangjäger irgendwie an ihn anschließen? Die Sache ist, dass es nicht wie getBean('MyBean').digest() genannt wird, es durch getBean('MyBean').sign(data) genannt wird, in dem Zeichen ist smth wieMethod Interceptor auf private Methoden

public byte[] sign(byte[] data){ 
    ... 
    b = digest(data); 
    ... 
    return signature; 
} 

Thx.

+0

Ich habe versucht, Ihren Code zu formatieren, aber es ist immer noch illegal. Bitte fügen Sie es richtig ein. – Bozho

Antwort

3

Auch wenn die Methode öffentlich ist, kann Spring keine Methodenaufrufe abfangen, die innerhalb des Objekts ausgeführt werden, das die Methode enthält. Um dies zu erreichen, müssten Sie AspectJ verwenden.

+0

Korrekt, Spring AOP arbeitet mit dynamischen Proxies, dh Sie können nur Methoden abfangen, die in einer Schnittstelle verfügbar sind und wenn der Proxy direkt an die exponierte Methode delegieren kann. – nkr1pt

+1

siehe http://forum.springsource.org/archive/index.php/t-34372.html – Cid54

+1

Dies ist nur für dynamische JDK-Proxies der Fall. Spring AOP kann auch mit CGLIB-Unterklassen-Proxies arbeiten. In diesem Fall funktioniert der Selbstaufruf öffentlicher Methoden problemlos. – skaffman

1

Art von voller AspectJ Voodoo, müssen Sie Ihre abgefangene Methode public machen. Wenn Sie die digest() Methode Ihrer Bean nicht als public offen legen möchten, aber dennoch Interzeptoren anwenden möchten, dann empfehle ich, Ihren Code zu refactorieren, um die Digest-Logik in eine separate Klasse zu extrahieren, die eine neue Digest-Schnittstelle implementiert und die Abfangjäger dazu.

Es ist ein wenig ungeschickt, aber es zwingt Sie, Ihre Bedenken zu trennen, was nicht schlecht ist.

0

Ein anderer Weg zu erreichen, was Sie wollen, ist eine Faul Klasse zu erstellen und die Anrufe abfangen, um es Digest() -Methode:

public interface Digester { 
    public Foo digest(byte[] data); 
} 

class DigesterImpl implements Digester { 
    public Foo digest(byte[] data) {...} 
} 

Dann im Frühjahr Code, den Sie injizieren ein proxied DigesterImpl Ihre Klasse und Call es:

private final Digester digester; 

MyClass(Digester digester) { 
    this.digester = digester; 
} 

public byte[] sign(byte[] data){ 
    ... 
    b = digester.digest(data); 
    ... 
    return signature; 
} 
0

der Schlüssel ist hier zu verstehen, dass das, wenn Aspect Programmierung unter Verwendung des Verfahrens fordert das Objekt Referenz werden Anrufe auf dem Proxy sein, und als solche den Proxy in der Lage, alle die delegieren Abfangjäger (a dvice), die für diesen bestimmten Methodenaufruf relevant sind.

Sobald jedoch der Aufruf das Zielobjekt schließlich erreicht hat, werden alle Methodenaufrufe, die er selbst ausführen kann, , z. B. Digest (Data), für diesen Verweis und nicht für den Proxy aufgerufen.

Dies hat wichtige Auswirkungen. Dies bedeutet, dass Self-Invocation nicht zu dem Hinweis führt, dass ein Methodenaufruf eine Ausführungswahrscheinlichkeit erhält. Aber es gibt einen Weg, es zu tun:

public byte[] sign(byte[] data){ 
    ... 
    b = (Digester)AopContext.currentProxy()).Digest(Data); 
    ... 
    return signature; 
} 

Dieser total Paare Code zu Spring AOP, und es macht die Klasse selbst sich der Tatsache bewusst, dass es in einem AOP Kontext verwendet wird, die im Gesicht fliegt von AOP.

Verwandte Themen