Intro til AspectJ

1. Introduksjon

Denne artikkelen er en rask og praktisk introduksjon til AspectJ.

Først skal vi vise hvordan du aktiverer aspektorientert programmering, og deretter fokuserer vi på forskjellen mellom kompileringstid, postkompilering og lastingstid.

La oss starte med en kort introduksjon av aspektorientert programmering (AOP) og AspectJs grunnleggende.

2. Oversikt

AOP er et programmeringsparadigme som tar sikte på å øke modulariteten ved å tillate atskillelse av tverrgående bekymringer. Det gjør det ved å legge til ekstra oppførsel til eksisterende kode uten å endre selve koden. I stedet erklærer vi separat hvilken kode som skal endres.

AspectJ implementerer både bekymringer og veving av kryssende bekymringer ved hjelp av utvidelser av Java-programmeringsspråk.

3. Maven-avhengigheter

AspectJ tilbyr forskjellige biblioteker, avhengig av bruken. Vi finner Maven-avhengigheter under gruppe org.aspectj i Maven Central-arkivet.

I denne artikkelen fokuserer vi på avhengigheter som trengs for å lage aspekter og Weaver ved hjelp av kompileringstid, etterkompilering og lastetid.

3.1. AspectJ Runtime

Når du kjører et AspectJ-program, bør klassestien inneholde klassene og aspektene sammen med AspectJ kjøretidsbibliotek aspectjrt.jar:

 org.aspectj aspectjrt 1.8.9 

Denne avhengigheten er tilgjengelig på Maven Central.

3.2. AspectJWeaver

I tillegg til AspectJ kjøretidsavhengighet, må vi også inkludere aspectjweaver.jar å introdusere råd til Java-klassen ved belastningstid:

 org.aspectj aspectjweaver 1.8.9 

Avhengigheten er også tilgjengelig på Maven Central.

4. Aspect Creation

AspectJ gir en implementering av AOP og har tre kjernekonsepter:

  • Bli med Point
  • Pointcut
  • Råd

Vi vil demonstrere disse konseptene ved å lage et enkelt program for å validere en brukerkontosaldo.

La oss først lage en Regnskap klasse med en gitt saldo og en metode for å ta ut:

offentlig klassekonto {int-saldo = 20; offentlig boolsk uttak (int-beløp) {if (balanse <beløp) {returner falsk; } saldo = saldo - beløp; returner sant; }}

Vi lager en AccountAspect.aj fil for å logge kontoinformasjon og for å validere kontosaldoen (merk at AspectJ-filer slutter med ".aj" filutvidelse):

offentlig aspekt AccountAspect {final int MIN_BALANCE = 10; pointcut callWithDraw (int beløp, konto acc): call (boolsk konto.withdraw (int)) && args (beløp) && target (acc); før (int beløp, kontokonto): callWithDraw (beløp, akk) {} boolsk rundt (int beløp, konto akk): callWithDraw (beløp, akk) {hvis (akk.balanse <beløp) {returner falsk; } retur fortsett (beløp, akk); } etter (int beløp, kontosaldo): callWithDraw (beløp, saldo) {}}

Som vi kan se, har vi lagt til en snarvei til uttaksmetoden og opprettet tre råder som refererer til det definerte snarvei.

For å forstå følgende introduserer vi følgende definisjoner:

  • Aspekt: En modularisering av en bekymring som skjærer over flere objekter. Hvert aspekt fokuserer på en bestemt tverrgående funksjonalitet
  • Bli med på punktet: Et punkt under utførelsen av et skript, for eksempel utførelse av en metode eller tilgang til eiendom
  • Råd: Handling utført av et aspekt på et bestemt sammenføyningspunkt
  • Pointcut: Et vanlig uttrykk som samsvarer med poeng. Et råd er assosiert med et snarveisuttrykk og kjører på et hvilket som helst tilknytningspunkt som samsvarer med snarveien

For mer informasjon om disse konseptene og deres spesifikke semantikk, kan det være lurt å sjekke ut følgende lenke.

Deretter må vi flette aspektene inn i koden vår. Avsnittene nedenfor tar for seg tre forskjellige typer veving: veving av kompileringstid, veving etter kompilering og veving av lastetid i AspectJ.

5. Veving av kompileringstid

Den enkleste tilnærmingen til veving er kompileringstid. Når vi har både kildekoden til aspektet og koden som vi bruker aspekter i, vil AspectJ-kompilatoren kompilere fra kilden og produsere en vevd klasse filer som utdata. Etterpå, etter kjøring av koden din, lastes vevingsprosessutgangsklassen inn i JVM som en vanlig Java-klasse.

Vi kan laste ned AspectJ utviklingsverktøy siden det inkluderer en medfølgende AspectJ kompilator. En av AJDTs viktigste funksjoner er et verktøy for visualisering av tverrgående bekymringer, som er nyttig for feilsøking av en snarveisspesifikasjon. Vi kan visualisere den kombinerte effekten selv før koden blir distribuert.

Vi bruker Mojo's AspectJ Maven Plugin til å veve AspectJ-aspekter inn i klassene våre ved hjelp av AspectJ-kompilatoren.

 org.codehaus.mojo aspectj-maven-plugin 1.7 1.8 1.8 1.8 true true ignorere UTF-8 kompilere test-kompilere 

For mer informasjon om alternativreferanse til AspectJ-kompilatoren, kan det være lurt å sjekke ut følgende lenke.

La oss legge til noen testtilfeller for kontoklassen vår:

offentlig klasse AccountTest {privat konto; @Før offentlig ugyldig før () {konto = ny konto (); } @Test offentlig ugyldig gitt20AndMin10_whenWithdraw5_thenSuccess () {assertTrue (account.withdraw (5)); } @Test offentlig ugyldig gitt20AndMin10_whenWithdraw100_thenFail () {assertFalse (account.withdraw (100)); }}

Når vi kjører testtilfellene, betyr teksten nedenfor som vises i konsollen at vi med hell vevde kildekoden:

[INFO] Bli med på punktet 'method-call (boolean com.baeldung.aspectj.Account.withdraw (int))' i Type 'com.baeldung.aspectj.test.AccountTest' (AccountTest.java:20) anbefalt av rundt råd fra 'com.baeldung.aspectj.AccountAspect' (AccountAspect.class: 18 (from AccountAspect.aj)) [INFO] Join point 'method-call (boolean com.baeldung.aspectj.Account.withdraw (int))' in Type ' com.baeldung.aspectj.test.AccountTest '(AccountTest.java:20) anbefalt av før råd fra' com.baeldung.aspectj.AccountAspect '(AccountAspect.class: 13 (fra AccountAspect.aj)) [INFO] Join point' method-call (boolsk com.baeldung.aspectj.Account.withdraw (int)) 'in Type' com.baeldung.aspectj.test.AccountTest '(AccountTest.java:20) rådes av etter råd fra' com.baeldung.aspectj .AccountAspect '(AccountAspect.class: 26 (from AccountAspect.aj)) 2016-11-15 22:53:51 [main] INFO com.baeldung.aspectj.AccountAspect - Saldo før uttak: 20 2016-11-15 22: 53:51 [main] INFO com.baeldung.aspectj.AccountAspect - Trekk ut ammout: 5 2016 -11-15 22:53:51 [hoved] INFO com.baeldung.aspectj.AccountAspect - Saldo etter uttak: 15 2016-11-15 22:53:51 [main] INFO com.baeldung.aspectj.AccountAspect - Balanse før uttak: 20 2016-11-15 22:53:51 [main] INFO com.baeldung.aspectj.AccountAspect - Trekk ut ammout: 100 2016-11-15 22:53:51 [main] INFO com.baeldung.aspectj.AccountAspect - Tilbaketrekking avvist! 2016-11-15 22:53:51 [main] INFO com.baeldung.aspectj.AccountAspect - Saldo etter uttak: 20

6. Veving etter kompilering

Veving etter kompilering (også noen ganger kalt binær veving) brukes til å veve eksisterende klassefiler og JAR-filer. Som med veving av kompileringstid, kan aspektene som brukes til veving være i kilde eller binær form, og de kan selv være vevd av aspekter.

For å gjøre dette med Mojo's AspectJ Maven Plugin, må vi konfigurere alle JAR-filene vi ønsker å veve i plugin-konfigurasjonen:

   org.agroup to-weave org.anothergroup gen 

JAR-filene som inneholder klassene som skal veves, må være oppført som i Maven-prosjektet og oppført som i av AspectJ Maven Plugin.

7. Veving av lastetid

Lastetidsveving er ganske enkelt binær veving utsatt til det punktet at en klasselaster laster en klassefil og definerer klassen til JVM.

For å støtte dette kreves en eller flere "vevklasselastere". Disse leveres enten eksplisitt av kjøretidsmiljøet eller aktiveres ved hjelp av et "vevemiddel".

7.1. Aktiverer Load-Time Weaving

AspectJ load-time weaving kan aktiveres ved hjelp av AspectJ agent som kan involvere seg i klassens lasteprosess og veve alle typer før de blir definert i VM. Vi spesifiserer javaagent alternativ til JVM -javaagent: pathto / aspectjweaver.jar eller ved hjelp av Maven-plugin for å konfigurere javaagent :

 org.apache.maven.plugins maven-surefire-plugin 2.10 -javaagent: "$ {settings.localRepository}" / org / aspectj / aspectjweaver / $ {aspectj.version} / aspectjweaver - $ {aspectj.version} .jar alltid sant 

7.2. Configuration Weaver

AspectJs lastetidsagent konfigureres ved bruk av aop.xml filer. Det ser etter en eller flere aop.xml filer på klassestien i META-INF katalog og samler innholdet for å bestemme veverkonfigurasjonen.

An aop.xml filen inneholder to viktige seksjoner:

  • Aspekter: definerer et eller flere aspekter til veveren og styrer hvilke aspekter som skal brukes i vevingsprosessen. De aspekter elementet kan valgfritt inneholde en eller flere inkludere og utelukke elementer (som standard brukes alle definerte aspekter til veving)
  • vever: definerer veveralternativer for vever og spesifiserer settet med typer som skal veves. Hvis ingen inkluderingselementer er spesifisert, vil alle typer som er synlige for veveren, bli vevd

La oss konfigurere et aspekt til veveren:

Som vi kan se, har vi konfigurert et aspekt som peker mot AccountAspect, og bare kildekoden i com.baeldung.aspectj pakken vil bli vevd av AspectJ.

8. Kommentaraspekter

I tillegg til den velkjente AspectJ-kodebaserte stilen for aspektdeklarasjon, støtter AspectJ 5 også en annotasjonsbasert stil for aspektdeklarasjon. Vi kaller uformelt settet med merknader som støtter denne utviklingsstilen for “@AspectJ”Merknader.

La oss lage en kommentar:

@Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public @interface Secured {public boolean isLocked () standard false; }

Vi bruker @Sikret kommentar for å aktivere eller deaktivere en metode:

offentlig klasse SecuredMethod {@Secured (isLocked = true) public void lockedMethod () {} @Secured (isLocked = false) public void unlockedMethod () {}}

Deretter legger vi til et aspekt ved hjelp av AspectJ-kommentar-stil, og sjekker tillatelsen basert på attributtet til @Secured-merknaden:

@Aspect offentlig klasse SecuredMethodAspect {@Pointcut ("@ kommentar (sikret)") offentlig ugyldig callAt (sikret sikret) {} @Around ("callAt (sikret)") offentlig Objekt rundt (fortsetterJoinPoint pjp, sikret sikret) kaster Kastbar {retur secure.isLocked ()? null: pjp.proceed (); }}

For mer detalj om AspectJ-kommentarstil, kan vi sjekke ut følgende lenke.

Deretter vever vi vår klasse og aspekt ved hjelp av lastetidsvever og put aop.xml under META-INF mappe:

Til slutt legger vi til enhetstest og sjekker resultatet:

@Test offentlig ugyldig testMethod () kaster unntak {SecuredMethod service = ny SecuredMethod (); service.unlockedMethod (); service.lockedMethod (); }

Når vi kjører testtilfellene, kan det hende vi sjekker konsollutgangen for å bekrefte at vi har vevd aspekt og klasse i kildekoden:

[INFO] Join point 'method-call (void com.baeldung.aspectj.SecuredMethod.unlockedMethod ())' in Type 'com.baeldung.aspectj.test.SecuredMethodTest' (SecuredMethodTest.java:11) anbefalt av rundt råd fra ' com.baeldung.aspectj.SecuredMethodAspect '(SecuredMethodAspect.class (fra SecuredMethodAspect.java)) 2016-11-15 22:53:51 [main] INFO com.baeldung.aspectj.SecuredMethod - ulåstMetode 2016-11-15 22:53 : 51 [hoved] INFO cbaspectj.SecuredMethodAspect - offentlig ugyldig com.baeldung.aspectj.SecuredMethod.lockedMethod () er låst

9. Konklusjon

I denne artikkelen dekket vi innledende konsepter om AspectJ. For detaljer, kan du ta en titt på AspectJ-hjemmesiden.

Du kan finne kildekoden for denne artikkelen på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found