Jordi
Jordi

Reputation: 23247

Spring AOP: After vs AfterReturning precedence

I've coded this code snippet:

@Aspect
@Component
public class ApiAuditAspect {

    @Pointcut(value = "execution(* net.gencat.transversal.espaidoc.api.controller.RepositoryController.*(..))")
    public void anyRepositoryController() {
        // Nothing to do here
    }

    @AfterReturning(
        pointcut = "anyRepositoryController()",
        returning = "result")
    public void audit(JoinPoint point, Object result) throws Throwable {
        // audit actions
    }

    @After("anyRepositoryController()")
    public void flush() {
        // flush all audits
    }

}

I've realized flush is executed before audit.

I though @After is executed after AfterReturning.

Any ideas about how to solve that?

Upvotes: 5

Views: 5985

Answers (3)

Anna OOkey
Anna OOkey

Reputation: 111

Starting with Spring 5.2. (released on 9 June 2020) the @After advice method is invoked AFTER any @AfterReturning or @AfterThrowing advice methods in the same aspect class

https://github.com/spring-projects/spring-framework/issues/25186

Upvotes: 7

Klaus
Klaus

Reputation: 1731

By default, for the aspects defined in the same class. There is no order in their execution. However, if you wish to order your aspects, each aspect should be in a separate class and the order should be declared with @Order annotation like below

@Order(1)
public class MyAudit{
 @AfterReturning(
        pointcut = "anyRepositoryController()",
        returning = "result")
    public void audit(JoinPoint point, Object result) throws Throwable {
        // audit actions
    }
}

@Order(6)
public class MyFlush{
    @After("anyRepositoryController()")
    public void flush() {
        // flush all audits
    }
}  

Lowest number is picked first and this can be a negative value since ordering is defined from Integer.MIN_VALUE to Integer.MAX_VALUE. And another thing is, if you define multiple classes with the same order value, then there is no guarantee which class will be picked first for the classes having the same order value

Upvotes: 2

JArgente
JArgente

Reputation: 2297

In the documentation there isn't nothing about the precedence or the order in which this two advices will execute. In fact they shouldn't be used togheter,

AfterReturning should be used when the method returns without exception

AfterThrowing should be used when the method throws an exception

After should be used instead of the previous two and needs to handle both cases.

So, I suggest you to get rid one of those and use make the flush call in AfterReturning just after the other code and if you need to execute this in case of an exception add other advice with @AfterThrowing calling the same method. Or use only @After and distinct there the two possible cases

Upvotes: 3

Related Questions