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

时间:2013-05-17 06:47:35

标签: 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
    }
}

我在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 个答案:

答案 0 :(得分: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