首页 文章

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

提问于
浏览
2

我对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
    }
}

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

DEBUG o.s.a.a.a.ReflectiveAspectJAdvisorFactory - Found AspectJ method...

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

@AfterThrowing(pointcut = "execution(* myPackage.service.*.save(*))", throwing = "ex")

但这也行不通 .

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

1 回答

  • 5

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

    @AfterThrowing(pointcut = "execution(* myPackage.service.Service.save(*))", throwing = "ex")
    

    工作良好 .

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

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

    <tx:annotation-driven transaction-manager="transactionManager" order="2000"/>
    

    然后在您的方面添加一个 @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
        }
    }
    

    看到:

    Spring AOP ordering - Transactions before Advise

相关问题