2010-09-02 15 views
5

Tutaj jest pytanie: Mam metodę digest(byte[] data). Powinien być prywatny, ponieważ naprawdę nie potrzebujemy go poza klasą, jednak nie umrę, jeśli go upublicznię, jeśli to pomoże.
Pytanie brzmi: czy mogę w jakiś sposób dołączyć do niego przechwytujący? Chodzi o to, że nie nazywa się jak getBean('MyBean').digest(), nazywana jest przez getBean('MyBean').sign(data) gdzie znak jest smth jakMetoda Przechwytuj na prywatnych metodach

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

Thx.

+0

Próbowałem sformatować kod, ale nadal jest on nielegalny. Wklej go poprawnie. – Bozho

Odpowiedz

3

Nawet jeśli metoda jest jawna, Spring nie może przechwytywać wywołań metod, które są wykonane z obiektu zawierającego metodę. Aby to osiągnąć, musisz użyć AspectJ.

+0

Prawidłowo, Spring AOP działa z dynamicznymi serwerami proxy, co oznacza, że ​​można przechwytywać tylko metody, które są widoczne w interfejsie i kiedy proxy może przekazywać bezpośrednio do ujawnionej metody. – nkr1pt

+1

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

+1

To tylko w przypadku dynamicznych serwerów proxy JDK. Spring AOP może również działać z serwerami podklas CGLIB, w którym to przypadku samo wywołanie publicznych metod działa dobrze. – skaffman

1

Rodzaj pełnego AspectJ voodoo, musisz zrobić przechwyconą metodę public. Jeśli nie chcesz ujawnić metody digest() fasoli jako public, ale nadal chcesz zastosować interpretery, sugeruję refaktoryzację kodu, aby wyodrębnić logikę digest do osobnej klasy, która implementuje nowy interfejs digest i zastosować przechwytywacze do tego.

To trochę niezgrabne, ale zmusza do oddzielenia obaw, co nie jest złe.

0

Innym sposobem osiągnięcia tego, co chcesz jest stworzenie klasy fermentacyjnej i przechwycić rozmowy na jego skrót() metoda:

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

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

Następnie w kodzie wiosennej Ci wstrzyknąć proxy DigesterImpl do swojej klasy i rozmowy to:

private final Digester digester; 

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

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

Kluczową rzeczą do zrozumienia jest to, że podczas korzystania Aspect programowania metodę wzywa tego odniesienia obiekt zostanie wzywa pełnomocnika, i jako taki pełnomocnik będzie mógł przekazać do wszystkich przechwytujące (a dvice), które są istotne dla tego konkretnego wywołania metody.

Jednak, gdy połączenie w końcu dotrze do obiektu docelowego, wszystkie wywołania metod, które może wykonać sam, , takie jak Digest (dane), będą wywoływane w odniesieniu do tego odniesienia, a nie do proxy.

Ma to ważne konsekwencje. Oznacza to, że samo-inwokacja nie spowoduje porady związanej z wywołaniem metody, która ma szansę na wykonanie. Ale istnieje sposób, aby to zrobić:

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

Ten całkowicie pary kod do Spring AOP, a to sprawia, że ​​klasa sama sobie sprawę z faktu, że jest on używany w kontekście AOP, która leci w obliczu AOP.

Powiązane problemy