Różnica pomiędzy call i execution w AspectJ

Różnica wredna, która potrafi zepsuć dzień.

Generalnie zarówno call jak i execution nie różnią się jeżeli chodzi o moment wywołania. Jeżeli zdefiniujemy, że mają być wkompilowane przed to zostaną wkompilowane przed. Jeżeli po to po. Kompilator zapewnia, że w danym przepływie sterowania aspekt będzie umieszczony w odpowiednim miejscu. Oczywiście przy założeniu, że nie ma tam jakiś dodatkowych aspektów. Różnica leży w tym gdzie kompilator umieszcza kod.

Położenie call

Jeżeli używamy call to kompilator umieści kod porady w miejscu gdzie wywoływana jest dana metoda. Czyli jeżeli metoda A.a woła metodę B.b to kod zostanie umieszczony w metodzie A.a.

Położenie execution

Jeżeli używamy execution to kompilator umieści kod w wywoływanej metodzie. Przykładowo jeżeli A.a woła B.b to kod zostanie umieszczony w B.b.

Gdzie jest to istotne

W praktyce jeżeli wrzucamy kod aspektowy do naszych klas to nie ma różnicy czy użyjemy call czy execution. Kompilator i tak musi przeorać cały kod źródłowy… no właśnie. Kod źródłowy… Jeżeli wasza metoda jest wywoływana przez jakaś zewnętrzną bibliotekę np. chcecie dodać kod aspektowy do testu oznaczonego @Test to użycie call skończy się komunikatem Xlint:adviceDidNotMatch. Kompilator nie doda waszej porady ponieważ nie pracuje na kodzie wywołującym metodę. Dotyczy to też sytuacji gdzie do wywołania metody używacie refleksji. W takim wypadku macie dwa wyjścia. Po pierwsze użyć execution, co jest prostsze, ale narusza wasz kod (przyjmuję tu pracę z weaveringiem w czasie kompilacji). Po drugie użyć call wraz z weaveringiem w czasie ładowania klas.

4 myśli na temat “Różnica pomiędzy call i execution w AspectJ

  1. 1. „przeorać cały kod źródłowy” – wszystkie znane mi techniki pracują na bajtkodzie. Kod źródłowy nie jest potrzbny.

    2. Istnieje możliwość nakładania aspektów na gotowe JARy, więc od biedy można zastosować execution na bibliotekach (ale tą drogą bym nie szedł).

    3. Zaletą execution jest umieszczenie wywołania aspektu w jednym miejscu (wlaściwej metodzie) a nie w 100 miejscach, gdzie jest ona wołana. Poza tym rodzi to również szereg problemów np. z refleksją, o czym słusznie wspominasz.

  2. ad 1. Mówię w dużym uproszczeniu. Generalnie chodzi mi o kod, który wyprodukujesz.
    ad 2. O, o tym nie wiedziałem 🙂
    ad 3. Z drugiej strony takie podejście ingeruje w nasz kod. Nie zawsze chcemy by był on wzbogacony o elementy aspektowe.

  3. Ad. 2: I nazywa się to „post-compile weaving” (cytując za „AspectJ in Action”, którą to z miejsca polecam [chociaż jestem dopiero na początku])

Napisz odpowiedź

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax