Spring AOP: @AfterThrowing execution pointcut never matches
I'm completely new to AOP. I need advice to write the correct pointcut. I have a service package that contains all service classes. All the classes implement the Service
interface. This interface has a method save(entity)
. My advice should be executed every time the service.save(entity)
method throws a DataIntegrityViolationException
.
Here the aspect:
@Component
@Aspect
public class DIVExceptionHandler {
@AfterThrowing(pointcut = "execution(* myPackage.service.Service.save(*))", throwing = "ex")
public void handleException(JoinPoint joinPoint, DataIntegrityViolationException ex) {
//snipped
}
}
I have both aspectj jars in the CP as explained in Spring AOP documentation and I have added <aop:aspectj-autoproxy/>
to Spring configuration and I'm using component scanning. In the log of the test I can see that the aspect is detected as aspetcj aspect:
DEBUG o.s.a.a.a.ReflectiveAspectJAdvisorFactory - Found AspectJ method...
So I believe this is not a configuartion issue and my pointcut expression is wrong. I also tried
@AfterThrowing(pointcut = "execution(* myPackage.service.*.save(*))", throwing = "ex")
But that did also not work.
So what is the correct pointcut expression?
it in fact was a configuration issue.
@AfterThrowing(pointcut = "execution(* myPackage.service.Service.save(*))", throwing = "ex")
Works fine.
The actual problem was that DataIntegrityViolationException
is only thrown after the proxy for @Transactional
completes the transaction. In my case this happened after my advice can be called.
The solution is to add an order attribute to transaction configuration:
<tx:annotation-driven transaction-manager="transactionManager" order="2000"/>
And then add an @Order
annotation to your aspect that is smaller than the one for the transaction:
@Component
@Order(1500) // must be less than order of <tx:annotation-driven />
@Aspect
public class DIVExceptionHandler {
@AfterThrowing(pointcut = "execution(* myPackage.service.Service.save(*))", throwing = "ex")
public void handleException(JoinPoint joinPoint, DataIntegrityViolationException ex) {
//snipped
}
}
See:
Spring AOP ordering - Transactions before Advise
链接地址: http://www.djcxy.com/p/77252.html