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.