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

Spring AOPドキュメントで説明されているように、CPに両方のaspectj jarがあり、 Spring構成に追加<aop:aspectj-autoproxy/>し、コンポーネントスキャンを使用しています。テストのログでは、アスペクトが aspetcj アスペクトとして検出されていることがわかります。

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

したがって、これは構成の問題ではなく、ポイントカット式が間違っていると思います。私も試しました

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

しかし、それもうまくいきませんでした。

では、正しいポイントカット式は何ですか?

4

1 に答える 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 の注文 - アドバイス前のトランザクション

于 2013-05-17T07:38:56.537 に答える