Reputation: 23247
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
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
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
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