Spring AOP:@AfterThrowing执行切入点从不匹配

beg*_*er_ 2 aspectj spring-aop

我对AOP完全不熟悉.我需要建议写出正确的切入点.我有一个包含所有服务类的服务包.所有类都实现了Service接口.该接口有一个方法save(entity).每次service.save(entity)方法抛出时我都应该执行我的建议DataIntegrityViolationException.

这方面:

@Component
@Aspect
public class DIVExceptionHandler {
    @AfterThrowing(pointcut = "execution(* myPackage.service.Service.save(*))", throwing = "ex")
        public void handleException(JoinPoint joinPoint, DataIntegrityViolationException ex) {
        //snipped
    }
}
Run Code Online (Sandbox Code Playgroud)

我在CP中有两个aspectj jar,如Spring AOP文档中所述,我已经添加<aop:aspectj-autoproxy/>到Spring配置中,我正在使用组件扫描.在测试的日志中,我可以看到方面被检测为aspetcj方面:

DEBUG o.s.a.a.a.ReflectiveAspectJAdvisorFactory - Found AspectJ method...
Run Code Online (Sandbox Code Playgroud)

所以我认为这不是一个配置问题,我的切入点表达是错误的.我也试过了

@AfterThrowing(pointcut = "execution(* myPackage.service.*.save(*))", throwing = "ex")
Run Code Online (Sandbox Code Playgroud)

但这也行不通.

那么正确的切入点表达是什么?

beg*_*er_ 5

它实际上是一个配置问题.

@AfterThrowing(pointcut = "execution(* myPackage.service.Service.save(*))", throwing = "ex")
Run Code Online (Sandbox Code Playgroud)

工作良好.

实际问题DataIntegrityViolationException是仅在@Transactional完成事务的代理之后抛出.在我的情况下,这可以在我的建议被召唤之后发生.

解决方案是向事务配置添加订单属性:

<tx:annotation-driven transaction-manager="transactionManager" order="2000"/>
Run Code Online (Sandbox Code Playgroud)

然后@Order为您的方面添加一个小于事务的注释:

@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
    }
}
Run Code Online (Sandbox Code Playgroud)

看到:

Spring AOP订购 - Advise之前的交易