1
2

More than 5 years have passed since last update.

SpringAOP インターセプタの呼び出し順

Posted at

Spring AOPによるアドバイスの呼び出し順についての自分メモ

Spring初心者です。ややこしいなと思ったことをなんとなくメモしていきます。今回はアドバイスの呼び出し順について。
仕様は以下にすべて書いていますが、忘れないように記録。
https://docs.spring.io/spring/docs/5.2.0.BUILD-SNAPSHOT/spring-framework-reference/core.html#aop-ataspectj-advice-ordering

1.同じJoinPointに適用されたAspectは、定義がない場合の呼び出し順は不定である。
2.@Order(もしくは@Priority、JavaDocを見る限りPriorityを使うべきか?)が定義されている場合は、@Orderのvalueが小さいものから順に呼び出される。
3.ただし、同じJoinPointに適用されたAspectが、同じAdviceに実装されている場合、そのアスペクトの実行順は不定になる。

3は、挙動を見る限り同じクラス(=Advice)に複数のAspectメソッドを実装し、同じJoinPointにそれらのメソッドがヒットした場合のこと。

WithinAdvice.java
@Component
@Aspect
public class WithinAdvice {

@Order(3)
    @Before("within(chapter2.g_aop..*)")
    public void logBeforeServieClassAndSubPackages(JoinPoint joinPoint) {
        // 指定したパッケージとそのサブパッケージにインターセプトします。
        // この場合、ServiceとHogeにインターセプトされます。
        System.out.println(String.format("%d logBeforeServieClassAndSubPackages : %s", 3, joinPoint.getSignature()));
    }

    @Before("within(chapter2.g_aop.others.Hoge+)")
    public void logBeforeHogeImplementClass(JoinPoint joinPoint) {
        // Hogeを実装した全メソッドを対象とします。
        System.out.println(String.format("%d logBeforeServieClassAndSubPackages : %s", 5, joinPoint.getSignature()));
    }
}

この場合、chapter2.g_aop.others.Hogeの実装クラスである、chapter2.g_aop.others.HogeImplを呼び出した場合、上記で呼び出されるAdviceの順番は、logBeforeServieClassAndSubPackages→logBeforeHogeImplementClassとはならない。

これを避けるためには、logBeforeServieClassAndSubPackages、logBeforeHogeImplementClassを別のクラスに切り出して実装する必要がある。つまり基本的には、1アドバイス(=クラス)にAspectメソッドを1つだけ実装するルールにした方が堅そう、ということっぽい。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2