Spring入門07 AOP


1.AOPが必要


🔲 すべてのメソッドの呼び出し時間を測定する場合
MemberServiceのjoin関数の呼び出し時間を測定します.
public Long join(Member member){
    // 같은 이름이 있는 중복 회원 가입 불가.
    long start = System.currentTimeMillis();

    try {
        validateDuplicateMember(member); // 중복 회원 검증
        memberRepository.save(member);
        return member.getId();
    } finally {
        long finish = System.currentTimeMillis();
        long timeMs = finish - start;
        System.out.println("join = "+timeMs+"ms");
    }
}

  • 方法開始時、開始時間startを測定します.

  • 方法終了時は時間をとり、例外が発生した場合も撮りますのでtry-finallyを使います.最後はいつも聞こえる
  • 上記のコードでは,会員加入のコアロジックを「コア管理事項(core concern)」と呼び,測定時間の機能は多様な方法に適用される汎用ロジックであるため,「共通関心事項(cross-cutting concern)」と呼ぶ.
    数千の方法があると仮定すると、上記のコードに示すように、以下の問題がある.
    ✔すべての方法で時間測定ロジックを記述するのは難しい.
    ✔時間を計測するロジックは個別の汎用ロジックとして作成できますが、難しすぎます.
    測定時間のロジックとコアビジネスロジックが混在しており、メンテナンスが困難です.
    測定時間の論理を変更する場合は、すべての論理を検索して変更します.
    この場合,AOPを用いることで効果的に問題を解決できる.

    2.AOPの適用


    2.1 AOPとは?


    上記の問題を解決する技術をビュー向けプログラミング(AOP)と呼ぶ.AOPは共通の関心事項と核心的な関心事項を分けている.方法には既に時間計測ロジックが追加されているが,AOPは時間計測ロジックを一つの場所に集約し,私が望む場所に適用する.
    ✔AOP応用前の時間測定ロジック

    ✔AOP応用後の時間測定ロジック

    2.2応用

    @Aspect
    @Component
    public class TimeTraceAop {
    
        @Around("execution(* hello.hellospring..*(..))")
        public Object execute(ProceedingJoinPoint joinPoint) throws Throwable{
            long start = System.currentTimeMillis();
            System.out.println("START: "+joinPoint.toString());
            try{
                return joinPoint.proceed();
            } finally {
                long finish = System.currentTimeMillis();
                long timeMs = finish-start;
                System.out.println("END: "+joinPoint.toString()+" "+timeMs+"ms");
            }
        }
    }

  • aopというパッケージを作成します.

  • その中でTimeTraceopというクラスを作ります

  • OPPに@Aspectのフレーズを付けるべきです.

  • 時間計測ロジックを作成します.

  • AOPをスプリング空席として登録します.

  • @Aroundプロンプトを使用して、共通の注目点を適用する範囲を設定します.
  • 🔲 joinPoint
    AOPはメソッドを呼び出すたびに中間から中断され、必要なコンテンツを操作できます.
    joinPoint.toString():どのメソッドを呼び出す名前を取得できますか.
    joinPoint.プロセス():次の方法で行います.
    以上の2つのほかにも多くの種類が存在する.見つけて使いましょう.
    🔲 スプリングシートにAOPを登録する
    AOPをスプリングシートとして登録してください.この場合、SpringConfigで@Beanを使用して登録するか、@Component操作を使用して@Componentを追加し、コンポーネントスキャンを使用して登録できます.SpringConfigを直接登録する方が良いですが、ここでは素子スキャンを使用します.
    🔲 @Aroundを使用して、共通の関心を適用する範囲を設定します.
    @Around宣言を使用すると、共通の関心事項を適用する範囲を設定できます.
    @Around("execution(*パッケージ名…クラス名(パラメータタイプ)")
    @Around("execution( hello.hellospring..(..))") : hello.hellospringパッケージに適用されるすべてのサブアイテム
    🔲 整理する
    AOPを通して、
    ✔核心管理事項と共通の関心事項を分離する.
    ✔コアの注目点を清潔に保つ.
    ✔時間を計測するためのロジックを個別の汎用ロジックに設定します.したがって、変更が必要な場合は、この論理のみが変更されます.
    ✔必要な適用対象を選択できます.

    2.3 AOPの行為


    AOPの動き方はいろいろあります.スプリング上のAOPの働き方について説明しましょう.
    ✔AOP応用前依存関係

    AOPが適用される前に、コントローラからサービスが呼び出されると、依存関係のみで呼び出されます.
    ✔AOP適用後の依存関係

    しかし、AOPが適用されるとSpringは「エージェント」と呼ばれる偽のメンバーサービスを作成し、コンテナにSpringBinを登録する際に、本物のSpringBinではなく偽SpringBinを前面に置きます.だから偽SpringBinが終わったらJoinPoint()を続けると、本物のspringbinが呼び出されます.したがって,memberControllerが呼び出すのは真のmemberServiceではなく,エージェント技術が生み出す偽のmemberServiceである.
    ✔AOP応用後の全図

    スプリング容器にスプリングシートを管理すれば,偽物を作製し依存性を注入することができる.これが依存注入の利点である.依存性を注入せずにコントローラ上で直接サービスを行うと,この技術自体は実現できない.コントローラの立場では依存性が注入されているため,直接受け入れて使用すると,非現実的なエージェントが入る.そのためOPPが可能です.
    このようなspringではエージェント方式と呼ばれるAOPである.