takeda_san’s blog

KotlinとVRを頑張っていく方向。

名前付きのPointcutって論理演算子で組み合わせができるって本当ですか?

きっかけ

SpringでAOPのAdvice対象を指定するPointcut式があるでないですか。
こんなの。

    @Before("execution(* jp.takeda.aoplogs..*.*(..))")
    fun before(joinPoint: JoinPoint) {
        println("beforeだよー")
    }

"execution(* jp.takeda.aoplogs.*.*(..))"
この指定でjp.takeda.aoplogsパッケージ配下のメソッドの開始時にログが出る。
さらに色々と条件を追加することで、意図した箇所だけがログの出力が埋め込めるわけです。

なんですが、例えばJavaConfigを入れている jp.takeda.aoplogs.config パッケージはログ対象にしたくない!みたいな、除外の指定ってどうやるんでしょうかね。
少し悩んでしまったので、メモ。

否定すればいいじゃない

タイトルですでに書いてあるので、その通りなのですが名前付きのPointcut式を定義しておくと、それに論理演算子を付けて否定とか論理積とかできるらしいです。
すばらしい。

さっきのコードで jp.takeda.aoplogs.config だけ除外したい場合はこうする。

    // すべてのクラスとメソッドを対象にする
    @Pointcut("execution(* jp.takeda.aoplogs..*.*(..))")
    fun loggingPattern() {
    }

    // config配下のすべてのクラスとメソッドを除外する
    @Pointcut("execution(* jp.takeda.aoplogs.config..*.*(..))")
    fun ignorePattern() {
    }

    @Before("loggingPattern() && ! ignorePattern()")
    fun before(joinPoint: JoinPoint) {
        println("beforeだよー")
    }

loggingPattern()ignorePattern() という2つのメソッドを追加しています。
これが名前付きPointcut式というらしいです。
なんか空のメソッドを定義のために作るって、ちょっと違和感ありますが無理やり納得しましょう。

@Before("loggingPattern() && ! ignorePattern()") ここで論理演算子で組み合わせることでconfigを対象外にすることができます。

最後に

正規表現と同じで複雑なPointcut式は、保守不能になるのでやめようね。
(後悔)