【Spring Boot】AOPを使ってアノテーションを自作してみた

2020年9月23日

目次

はじめに

お世話になります、hosochinです

さて、今回は
「Spring BootのAOPを使ってアノテーションを自作」
です

AOPとは

AOPとはアスペクト指向プログラミングの略です

アスペクト指向プログラミング(アスペクトしこうプログラミング、Aspect Oriented Programming、AOP)は、オブジェクト指向ではうまく分離できない特徴(クラス間を横断 (cross-cutting) するような機能)を「アスペクト」とみなし、アスペクト記述言語をもちいて分離して記述することでプログラムに柔軟性をもたせようとする試み

wikipedia

・・・・まあ、あれです、ログ出力とか例外のハンドリングといった、複数モジュールにまたがった処理は切り出して一箇所に集めると思うんですけど、それを実現する手法のこと(だと思ってます)
で、SpringにもこのAOPの機能があるので今回はそれを使ってみたいと思います

サンプル

文字列を受け取って大文字や小文字に変換して返すというコントローラを作りたいと思います
この大文字 or 小文字に変換して返すという処理を自作アノテーションで実現したいと思います
アノテーションを定義しているところの @Target や @Retention については別の記事でまとめてありますのでそちらを参考にしてください

  • アノテーションを定義したクラス
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    ConversionType conversionType();
    enum ConversionType {
        UPPER,
        LOWER
    }
}
  • AOP部分
@Aspect
@Component
public class AnnotationUtils {
    @Around("@annotation(com.example.demo.myannotation.MyAnnotation)")
    public String myAnnotationImpl(JoinPoint jp) {
        // controllerで受け取った引数を取り出す
        if(ArrayUtils.isEmpty(jp.getArgs())) {
            return "";
        }
        String arg = String.valueOf(jp.getArgs()[0]);

        MethodSignature signature = (MethodSignature) jp.getSignature();
        MyAnnotation instance = signature.getMethod().getAnnotation(MyAnnotation.class);

        switch (instance.conversionType()) {
            case UPPER:
                // 大文字に変換
                return arg.toUpperCase();
            case LOWER:
                // 小文字に変換
                return arg.toLowerCase();
            default:
                return "";
        }
    }
}
  • 自作アノテーションを付与したコントローラ
@RestController
@RequestMapping
public class SampleController {

    /**
     * リクエストパラメータの文字列を大文字に変換して返すcontroller
     */
    @GetMapping("/upper-case")
    @MyAnnotation(conversionType = MyAnnotation.ConversionType.UPPER)
    public String getUpperCase(@RequestParam(name = "message") String message) {
        return message;
    }

    /**
     * リクエストパラメータの文字列を小文字に変換して返すcontroller
     */
    @GetMapping("/lower-case")
    @MyAnnotation(conversionType = MyAnnotation.ConversionType.LOWER)
    public String getLowerCase(@RequestParam(name = "message") String message) {
        return message;
    }
}
  • 実行結果
curl "http://localhost:8080/upper-case?message=test"
TEST
curl "http://localhost:8080/lower-case?message=TEST"
test

まとめ

とりあえずやりたいことはできました
まあ今回の場合とかは普通にサービスクラスでも切ってそっちでやれよって感じがしますが。。。
ログ出力やエラーハンドリングなんかは自分で定義したアノテーション使ってみるといいかもですね!
Spring-bootのAOPについてはまたどこかでまとめたいと思います

技術AOP,SpringBoot

Posted by hosochin