##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にそれらのメソッドがヒットした場合のこと。
@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つだけ実装するルールにした方が堅そう、ということっぽい。