【问题标题】:Spring AOP: @AfterThrowing execution pointcut never matchesSpring AOP:@AfterThrowing 执行切入点从不匹配
【发布时间】:2013-05-12 06:26:59
【问题描述】:

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

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

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

所以我相信这不是配置问题,我的切入点表达是错误的。我也试过了

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

但这也没有用。

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

【问题讨论】:

    标签: aspectj spring-aop


    【解决方案1】:

    实际上是配置问题。

    @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

    【讨论】:

      猜你喜欢
      • 2013-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多