Inleiding tot adviestypes in het voorjaar

1. Overzicht

In dit artikel bespreken we verschillende soorten AOP-adviezen die in het voorjaar kunnen worden opgesteld.

Advies is een actie die wordt uitgevoerd door een aspect op een bepaald verbindingspunt. Verschillende soorten advies zijn onder meer "rond", "voor" en "na" advies. Het belangrijkste doel van aspecten is het ondersteunen van transversale problemen, zoals logboekregistratie, profilering, caching en transactiebeheer.

En als je dieper wilt ingaan op pointcut-uitdrukkingen, bekijk dan de vorige intro hiervan.

2. Advies mogelijk maken

Met Spring kunt u advies geven met behulp van AspectJ-annotaties, maar dat moet u eerst pas de @EnableAspectJAutoProxy annotatie bij uw configuratieklasse, wat ondersteuning mogelijk maakt voor het omgaan met componenten die zijn gemarkeerd met AspectJ's @Aspect annotatie.

@Configuration @EnableAspectJAutoProxy openbare klasse AopConfiguration {...}

2.1. Spring Boot

In Spring Boot-projecten hoeven we de @EnableAspectJAutoProxy. Er is een toegewijde AopAutoConfiguration die Spring's AOP-ondersteuning mogelijk maakt als het Aspect of Advies is op het klassenpad.

3. Voor advies

Dit advies wordt, zoals de naam al aangeeft, uitgevoerd vóór het verbindingspunt. Het voorkomt niet de voortdurende uitvoering van de methode die het adviseert, tenzij er een uitzondering wordt gegenereerd.

Overweeg het volgende aspect dat eenvoudig de naam van de methode registreert voordat deze wordt aangeroepen:

@Component @Aspect openbare klasse LoggingAspect {privé Logger-logger = Logger.getLogger (LoggingAspect.class.getName ()); @Pointcut ("@ target (org.springframework.stereotype.Repository)") openbare ongeldige repositoryMethods () {}; @Before ("repositoryMethods ()") openbare ongeldige logMethodCall (JoinPoint jp) {String methodName = jp.getSignature (). GetName (); logger.info ("Before" + methodName); }}

De logMethodCall advies zal worden uitgevoerd voordat enige repository-methode gedefinieerd door de repositoryMethods pointcut.

4. Na advies

Na advies, aangegeven met behulp van de @Na annotatie, wordt uitgevoerd na de uitvoering van een overeenkomende methode, ongeacht of er een uitzondering is gegenereerd.

In sommige opzichten lijkt het op een Tenslotte blok. Als u advies nodig heeft om alleen te worden geactiveerd na een normale uitvoering, moet u de advies teruggeven verklaard door @Na terugkeer annotatie. Als u wilt dat uw advies alleen wordt geactiveerd wanneer de doelmethode een uitzondering genereert, moet u advies gooien, verklaard met behulp van de @AfterThrowing annotatie.

Stel dat we enkele applicatiecomponenten willen informeren wanneer een nieuw exemplaar van Foo is gecreëerd. We zouden een evenement kunnen publiceren van Foobao, maar dit zou in strijd zijn met het beginsel van enkele verantwoordelijkheid.

In plaats daarvan kunnen we dit bereiken door het volgende aspect te definiëren:

@Component @Aspect openbare klasse PublishingAspect {privé ApplicationEventPublisher eventPublisher; @Autowired openbare ongeldige setEventPublisher (ApplicationEventPublisher eventPublisher) {this.eventPublisher = eventPublisher; } @Pointcut ("@ target (org.springframework.stereotype.Repository)") public void repositoryMethods () {} @Pointcut ("execution (* * .. create * (Long, ..))") public void firstLongParamMethods ( ) {} @Pointcut ("repositoryMethods () && firstLongParamMethods ()") public void entityCreationMethods () {} @AfterReturning (value = "entityCreationMethods ()", return = "entity") public void logMethodCall (JoinPoint jp, Object entity) gooit Throwable {eventPublisher.publishEvent (nieuwe FooCreationEvent (entiteit)); }}

Merk allereerst op dat door gebruik te maken van de @AfterReturning annotatie hebben we toegang tot de retourwaarde van de doelmethode. Ten tweede door een parameter van het type JoinPoint, we hebben toegang tot de argumenten van de aanroep van de doelmethode.

Vervolgens maken we een luisteraar die eenvoudig de gebeurtenis registreert:

@Component openbare klasse FooCreationEventListener implementeert ApplicationListener {private Logger-logger = Logger.getLogger (getClass (). GetName ()); @Override public void onApplicationEvent (FooCreationEvent-gebeurtenis) {logger.info ("Foo-instantie gemaakt:" + event.getSource (). ToString ()); }}

5. Rond advies

Rond advies omringt een join-punt, zoals een methode-aanroep.

Dit is het krachtigste soort advies. Around Advice kan aangepast gedrag uitvoeren, zowel voor als na het aanroepen van de methode. Het is ook verantwoordelijk om te kiezen of u door wilt gaan naar het join-punt of om de uitvoering van de geadviseerde methode te verkorten door een eigen retourwaarde op te geven of een uitzondering te genereren.

Stel dat we de uitvoeringstijd van de methode willen meten om het gebruik ervan te demonstreren. Laten we hiervoor een aspect maken:

@Aspect @Component openbare klasse PerformanceAspect {privé Logger-logger = Logger.getLogger (getClass (). GetName ()); @Pointcut ("binnen (@ org.springframework.stereotype.Repository *)") openbare ongeldige repositoryClassMethods () {}; @Around ("repositoryClassMethods ()") openbaar object measureMethodExecutionTime (ProceedingsJoinPoint pjp) gooit Throwable {lange start = System.nanoTime (); Object retval = pjp.proceed (); lange einde = System.nanoTime (); String methodName = pjp.getSignature (). GetName (); logger.info ("Uitvoering van" + methodName + "nam" + TimeUnit.NANOSECONDS.toMillis (einde - start) + "ms"); terugkeer retval; }}

Dit advies wordt geactiveerd wanneer een van de join-punten overeenkomt met de repositoryClassMethods pointcut wordt uitgevoerd.

Voor dit advies is één parameter van het type nodig Doorgaan met JointPoint. De parameter geeft ons de mogelijkheid om actie te ondernemen voordat de doelmethode wordt aangeroepen. ikIn dit geval slaan we eenvoudig de starttijd van de methode op.

Ten tweede is het type adviesretour Voorwerp aangezien de doelmethode een resultaat van elk type kan retourneren. Als de doelmethode is leegte,nul zal worden geretourneerd. Na de aanroep van de doelmethode kunnen we de timing meten, deze registreren en de resultaatwaarde van de methode terugsturen naar de beller.

6. Overzicht

In dit artikel hebben we de verschillende soorten advies in Spring en hun verklaringen en implementaties geleerd. We hebben aspecten gedefinieerd met behulp van een op schema's gebaseerde benadering en met behulp van AspectJ-annotaties. Ook hebben wij diverse mogelijke adviesaanvragen verzorgd.

De implementatie van al deze voorbeelden en codefragmenten is te vinden in mijn GitHub-project.