Spring AOP vs AspectJ

178

Mam wrażenie, że Spring AOP najlepiej nadaje się do zadań specyficznych dla aplikacji, takich jak bezpieczeństwo, logowanie, transakcje itp., Ponieważ wykorzystuje niestandardowe adnotacje Java5 jako szkielet. Jednak AspectJ wydaje się być bardziej przyjaznym wzorcem projektowym.

Czy ktoś może wskazać różne zalety i wady używania Spring AOP i AspectJ w aplikacji Spring?

babydudecoder
źródło
3
Jeśli jakaś adnotacja istnieje w Spring, ale istnieje również w Javie, czego należy użyć? Jawa. Ta sama logika dotyczy tej funkcji. Wiosna to wiosna. dzisiaj minęło jutro. (Pamiętaj, że ludzie używali Struts jakiś czas przed wiosną). AspectJ jest preferowanym rozwiązaniem długoterminowym. To przetrwa wiosnę. Nie odrzucam Springa, tylko mówię, w tym aspekcie ...: -;
inor

Odpowiedzi:

236

Spring-AOP Plusy

  • Jest prostszy w użyciu niż AspectJ, ponieważ nie musisz używać LTW ( tkanie w czasie ładowania ) ani kompilatora AspectJ.

  • Używa wzorca Proxy i wzorca Decorator

Wady Spring-AOP

  • Jest to AOP oparty na proxy, więc w zasadzie można używać tylko punktów złączenia wykonania metody.
  • Aspekty nie są stosowane podczas wywoływania innej metody w tej samej klasie.
  • Może być trochę narzutu czasu wykonania.
  • Spring-AOP nie może dodać aspektu do niczego, co nie jest tworzone przez fabrykę Springa

AspectJ Pros

  • Obsługuje wszystkie punkty złączenia. Oznacza to, że możesz zrobić wszystko.
  • Jest mniej czasu pracy niż w przypadku Spring AOP.

AspectJ Cons

  • Bądź ostrożny. Sprawdź, czy twoje aspekty są utkane tylko z tym, co chciałeś być utkany.
  • Potrzebujesz dodatkowego procesu kompilacji z AspectJ Compiler lub musisz skonfigurować LTW (tkanie w czasie ładowania)
Whiteship
źródło
20
@Configurable wymaga użycia AspecJ przez Spring. Z dokumentów:If you need to advise objects not managed by the Spring container (such as domain objects typically), then you will need to use AspectJ.
HDave
7
Kolejnym wiosennym oszustwem są dla mnie nieczytelne długie śledzenie stosu ze względu na podejście oparte na proxy
wrm
1
Myląca część odpowiedzi: jak niewielki narzut czasu wykonania jest dla profesjonalisty dla jednego narzędzia, a możliwość posiadania małego narzutu czasu wykonania, a dla drugiego?
Moreaki
16
@Moreaki: Powiedział „trochę z góry” jako oszust i „trochę z góry” jako profesjonalista. Pojedyncza różnica „a” jest bardzo ważna - w języku angielskim „trochę” oznacza „trochę”, podczas gdy „mało” oznacza „prawie nic”.
wujek
1
Krótka wątpliwość - w Twoim Spring AOP Pros (2nd point) - jeśli użyjemy adnotacji @Aspect na wiosnę, będzie to aspekt czas). Ponieważ mam wrażenie, że AspectJ to czas kompilacji, a Spring AOP to AOP czasu wykonywania. Pls help
Pedantic
21

Oprócz tego, co powiedzieli inni - żeby przeformułować there are two major differences:

  1. Jeden jest związany z rodzajem tkania.
  2. Kolejny do definicji punktu złączenia.

Spring-AOP: przeplatanie środowiska wykonawczego przez proxy przy użyciu koncepcjidynamic proxy if interface exists or cglib library if direct implementation provided.

AspectJ: Przeplatanie czasu kompilacji, AspectJ Java Tools(ajc compiler)jeśli dostępne jest źródło, lub przeplatanie po kompilacji (przy użyciu skompilowanych plików). Można również włączyć splatanie czasu ładowania w Spring - wymaga aspectjpliku definicji i zapewnia elastyczność.

Wyplatanie czasu kompilacji może zapewnić korzyści związane z wydajnością (w niektórych przypadkach), a także joinpoint definition in Spring-aop is restricted to method definition only which is not the case for AspectJ.

techzen
źródło
20

Dodatkowa uwaga: jeśli ważna jest wydajność przy dużym obciążeniu, potrzebujesz AspectJ, który jest 9-35x szybszy niż Spring AOP . 10 ns w porównaniu z 355 ns może nie wydawać się dużo, ale widziałem ludzi używających WIELE aspektów. Wartość 10 tys. Aspektów. W takich przypadkach Twoje żądanie może dotyczyć tysięcy aspektów. W takim przypadku dodajesz ms do tego żądania.

Zobacz testy porównawcze .

Joseph Lust
źródło
14

Spring AOP jest jedną z podstawowych części ramy sprężynowej. Na bardzo podstawowym etapie ramy wiosenne są oparte na IoC i AOP. W oficjalnym przebiegu wiosny jest slajd, na którym jest napisane:

AOP jest jedną z najważniejszych części frameworka.

Kluczową kwestią do zrozumienia, jak działa AOP w Spring, jest to, że pisząc Aspect za pomocą Spring, oprzyrządujemy framework, budując proxy dla twoich obiektów, z JDKDynamicProxy jeśli twój bean implementuje interfejs lub przez CGLIB, jeśli twój bean nie implementuje żadnego berło. Pamiętaj, że musisz mieć cglib 2.2 w swojej ścieżce klas, jeśli używasz Springa przed wersją 3.2. Począwszy od Spring 3.2 jest bezużyteczny, ponieważ cglib 2.2 był zawarty w rdzeniu.

Struktura przy tworzeniu fasoli utworzy proxy, które otacza twoje obiekty i dodaje obowiązki związane z przekrojami, takie jak bezpieczeństwo, zarządzanie transakcjami, logowanie i tak dalej.

Tworzenie proxy w ten sposób zostanie zastosowane począwszy od wyrażenia pointcut, które instrumentuje strukturę do decydowania, jakie komponenty bean i metody zostaną utworzone jako proxy. Rada będzie bardziej odpowiedzialna niż za Twój kod. Pamiętaj, że w tym procesie punkt cięcia przechwytuje tylko metody publiczne, które nie są zadeklarowane jako ostateczne.

Teraz, podczas gdy w wiosennym AOP tkanie aspektów będzie wykonywane przez kontener podczas uruchamiania kontenera, w AspectJ musisz to zrobić z kompilacją kodu po modyfikacji kodu bajtowego. Z tego powodu moim zdaniem podejście Spring jest prostsze i łatwiejsze w zarządzaniu niż AspectJ.

Z drugiej strony, w Spring AOP nie możesz wykorzystać całej mocy AOP, ponieważ implementacja odbywa się przez proxy, a nie poprzez modyfikację twojego kodu.

Podobnie jak w AspectJ, w SpringAOP możesz użyć tkania w czasie ładowania. Możesz skorzystać z tej funkcji wiosną jest zaimplementowana z agentem i specjalnymi konfiguracjami @EnabledLoadWeavinglub w formacie XML. Możesz użyć przestrzeni nazw jako przykładu. Jednak w Spring AOP nie można przechwycić wszystkich przypadków. Na przykład newpolecenie nie jest obsługiwane w Spring AOP.

Jednak w Spring AOP możesz skorzystać z AspectJ poprzez użycie aspectofmetody fabrycznej w fasoli konfiguracji sprężyn.

Z tego powodu Spring AOP jest w zasadzie proxy utworzonym z pojemnika, więc możesz używać AOP tylko dla wiosennych ziaren. Podczas gdy z AspectJ możesz używać aspektu we wszystkich swoich ziarnach. Kolejnym punktem porównania jest debugowanie i przewidywalność zachowania kodu. W przypadku Spring AOP zadanie jest wykonywane w całości z kompilatora Java, a aspekty są bardzo fajnym sposobem tworzenia proxy dla beana Spring. W AspectJ, jeśli modyfikujesz kod, potrzebujesz więcej kompilacji i zrozumienia, gdzie tkane są twoje aspekty, może być trudne. Nawet wyłączenie tkania wiosną jest prostsze: za pomocą sprężyny usuwasz aspekt z konfiguracji, restartujesz i działa. W AspectJ musisz przekompilować kod!

W tkaniu w czasie ładowania AspectJ jest bardziej elastyczny niż Spring, ponieważ Spring nie obsługuje wszystkich opcji AspectJ. Ale moim zdaniem, jeśli chcesz zmienić proces tworzenia fasoli, lepszym sposobem jest zarządzanie niestandardowym logowaniem w fabryce, a nie tkanie w czasie ładowania aspektu, który zmienia zachowanie twojego nowego operatora.

Mam nadzieję, że ta panorama AspectJ i Spring AOP pomoże ci zrozumieć różnicę między tymi dwoma miksturami

Valerio Vaudi
źródło
0

Ważne jest, aby rozważyć, czy Twoje aspekty będą miały kluczowe znaczenie dla misji i gdzie Twój kod jest wdrażany. Wiosenny AOP oznacza, że ​​polegasz na tkaniu w czasie ładowania. To może się nie udać i z mojego doświadczenia wynika, że ​​mogą istnieć zarejestrowane błędy, ale nie uniemożliwi to uruchomienia aplikacji bez kodu aspektu [Dodałbym zastrzeżenie, że może być możliwe skonfigurowanie go w taki sposób, że nie jest to walizka; ale osobiście nie jestem tego świadomy ]. Pozwala to uniknąć tkania w czasie kompilacji.

Dodatkowo, jeśli używasz AspectJ w połączeniu z wtyczką Aspectj-maven, możesz uruchomić testy jednostkowe dla swoich aspektów w środowisku CI i mieć pewność, że zbudowane artefakty są testowane i prawidłowo tkane. Chociaż z pewnością możesz napisać testy jednostkowe oparte na Spring, nadal nie masz gwarancji, że wdrożony kod będzie tym, który został przetestowany, jeśli LTW zawiedzie.

Inną kwestią jest to, czy hostujesz aplikację w środowisku, w którym możesz bezpośrednio monitorować powodzenie lub niepowodzenie uruchamiania serwera / aplikacji, lub czy aplikacja jest wdrażana w środowisku, w którym nie jest pod Twoim nadzorem [np. jest hostowany przez klienta]. Ponownie, wskazywałoby to sposób na skompilowanie tkania czasu.

Pięć lat temu zdecydowanie bardziej opowiadałem się za AOP skonfigurowanym przez Spring z tego prostego powodu, że łatwiej było z nim pracować i rzadziej żuć moje IDE. Jednak wraz ze wzrostem mocy obliczeniowej i dostępnej pamięci stało się to znacznie mniejszym problemem, a CTW z wtyczką Aspectj-maven stało się lepszym wyborem w moim środowisku pracy w oparciu o powody, które opisałem powyżej.

kcampbell
źródło
0

Ten artykuł zawiera również dobre wyjaśnienie tematu.

Spring AOP i AspectJ mają różne cele.

Spring AOP ma na celu zapewnienie prostej implementacji AOP w Spring IoC w celu rozwiązania najczęstszych problemów, z którymi borykają się programiści.

Z drugiej strony AspectJ jest oryginalną technologią AOP, która ma na celu zapewnienie kompletnego rozwiązania AOP.

gce
źródło
0

W porównaniu do AOP, AspectJ nie musi ulepszać klasy docelowej w czasie kompilacji. Zamiast tego generuje klasę proxy dla klasy docelowej w czasie wykonywania, która albo implementuje ten sam interfejs, co klasa docelowa, albo jest podklasą klasy docelowej.

Podsumowując, instancja klasy proxy może być używana jako instancja klasy docelowej. Ogólnie rzecz biorąc, platforma AOP ulepszona w czasie kompilacji jest bardziej korzystna pod względem wydajności - ponieważ struktura AOP rozszerzona w czasie wykonywania wymaga dynamicznych ulepszeń za każdym razem, gdy jest uruchomiona.

Jerry Hsu
źródło