スプリングAOP基本概念



ソースとコメント


https://engkimbs.tistory.com/746
https://docs.spring.io/spring-framework/docs/2.5.x/reference/aop.html

スプリングAOP


AOP : Aspect Oriented Programming
AOPは観点に向けたプログラミングと呼ばれている.観点ガイドは簡単に言えば,ある論理を基準として,それを核心観点,付加観点に分け,その観点を基準としてそれぞれモジュール化する.ここで、モジュール化とは、ある共通の論理または機能を1つの単位に組み合わせることを意味する.
たとえば、コア・コンセプトは最終的には、コア・ロジックを実行するデータベース接続、ログ・レコード、ファイル入出力など、コア・ビジネス・ロジックに適用されるコア・ビジネス・ロジックになります.
AOPでは,各観点を基準として論理をモジュール化しているが,これはコードを部分的にモジュール化することを意味する.このとき、ソースコードの間に他の部分のコードが繰り返し書き込まれていることがわかります.これを分散の注目点(CrosscuttingConcerns)と呼びます.

上記分散した注目点をモジュール化し,コアビジネスロジックから分離して再利用することを目的とする.

AOPキーコンセプト

  • Aspect
  • 上記分散する関心モジュールを
  • にする.
    付加機能を
  • 株にモジュール化した.
  • Target
  • ビュー(クラス、メソッド...)
  • Advice
  • 実際に何をすべきかについての
  • 実付加機能実装体
  • JoinPoint
  • Adviceは複数の時点に適用されます:
  • PointCut
  • JoinPointの詳細仕様が定義されています.
  • 2A란 메서드의 진입 시점에 호출 할 것のように、Adivceの動作点をより具体的に決定することができる.
  • AOP特性

  • エージェントモードに基づくAOP実装
  • エージェントオブジェクトを使用する理由は、アクセス制御および追加機能を追加するためです.
  • AOPは
  • スプリングボックス
  • にのみ適用する.
  • は、すべてのAOP機能を提供するのではなく、スプリングIoCと組み合わせて使用されます.これは、エンタープライズ・アプリケーションで最も一般的な問題です(重複コード、エージェント・クラスの作成の面倒さ、およびオブジェクト間の結合...)正しい解決策を支持する.
  • スプリングAOP:@AOP


    スプリング@AOPを使用するには、次の依存性を追加する必要があります.
    // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop
    	implementation 'org.springframework.boot:spring-boot-starter-aop:2.6.2'
    次に、「チェック」を表すクラスであることを示す@Aspect注記を貼り付け、@Component springbineとして登録します.

    TestAspect

    @Aspect
    @Component
    public class TestAspect {
    
        @Around("execution(* me.dragonappear..*.EventService.*(..))")
        public Object log(ProceedingJoinPoint pjp) throws Throwable {
            long begin = System.currentTimeMillis();
            Object retVal = pjp.proceed(); // 메서드 호출 자체를 감싼다
            System.out.println(System.currentTimeMillis() - begin);
            return retVal;
        }
    }
    @Aroundは、特定のAdviceがターゲット方法の周囲で実行されることを示す.上記のコードのAdviceは、ターゲットメソッドの実行時間を測定するための論理を実現する.さらに、execution(*me.dragonappear..*.EventService.*(..))は、me.dragonappearの下のパン経路のEventServiceオブジェクトに対するすべての方法を適用することを意味する.

    EventService

    public interface EventService {
        void createEvent();
    
        void publishEvent();
    
        void deleteEvent();
    }

    EventServiceImpl

    @Component
    public class EventServiceImpl implements EventService{
    
        @Override
        public void createEvent() {
            try {
                Thread.sleep(1000);
            } catch(InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Created an event");
        }
    
        @Override
        public void publishEvent() {
            try {
                Thread.sleep(1000);
            } catch(InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Published an event");
        }
    
        @Override
        public void deleteEvent() {
            System.out.println("Delete an event");
        }
    }

    AppRunner

    @RequiredArgsConstructor
    @Service
    public class AppRunner implements ApplicationRunner {
        private final EventService eventService;
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            eventService.createEvent();
            eventService.publishEvent();
            eventService.deleteEvent();
        }
    }

    Result

    Created an event
    1033
    Published an event
    1005
    Delete an event
    0
    さらに、パス指定メソッドではなく、特定の位置決めポイントで評価を実行する機能も提供します.

    TestLogging

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.CLASS)
    public @interface TestLogging {
    }

    TestAspect

    @Around("@annotation(TestLogging)")
        public Object log(ProceedingJoinPoint pjp) throws Throwable {
            long begin = System.currentTimeMillis();
            Object retVal = pjp.proceed(); // 메서드 호출 자체를 감싼다
            System.out.println(System.currentTimeMillis() - begin);
            return retVal;
        }

    EventServiceImpl

    @Component
    public class EventServiceImpl implements EventService{
    
        @TestLogging
        @Override
        public void createEvent() {
            try {
                Thread.sleep(1000);
            } catch(InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Created an event");
        }
    
        @Override
        public void publishEvent() {
            try {
                Thread.sleep(1000);
            } catch(InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Published an event");
        }
    
        @Override
        public void deleteEvent() {
            System.out.println("Delete an event");
        }
    }

    Result

    Created an event
    1041
    Published an event
    Delete an event
    上記の出力結果では、Aspectに説明が付加された方法のみが適用される.
    同様に,Spring Binのすべての方法に適用できる機能も提供した.

    TestAspect

    @Around("bean(eventServiceImpl)")
        public Object log(ProceedingJoinPoint pjp) throws Throwable {
            long begin = System.currentTimeMillis();
            Object retVal = pjp.proceed(); // 메서드 호출 자체를 감싼다
            System.out.println(System.currentTimeMillis() - begin);
            return retVal;
        }

    Result

    Created an event
    1048
    Published an event
    1004
    Delete an event
    0
    上記の出力結果から、eventServiceImplのすべてのメソッドに対応するビューが追加されていることがわかります.
    また、@TestLoggingに加えて、ターゲットメソッドの実行時間を指定できるプレゼンテーションもあります.
    @機能@Before(前)デバイスターゲットメソッドを呼び出す前にデバイス機能を実行@After(後)ターゲットメソッドの結果にかかわらず(成功するかどうかにかかわらず)、ターゲットメソッドが完了したときにデバイス機能を実行@AfterReturn(正常に戻った後)ターゲットメソッドが結果値を正常に返した後、ターゲットメソッドが異常処理(異常発生後)を実行するときに異常を投げ出すと、異常処理(メソッド実行前後)を実行するデバイスがターゲットメソッドを囲み、ターゲットメソッドを呼び出す前と後にデバイス機能を実行します.