Section 5. Spring AOP


スプリングAOPコンセプト
AOP(Aspect-Oriented-Programming)
OOPを補完とするモジュール化可能なばらばらビューのプログラミング方法
分散した注目点
Concernsとは、複数のクラスにわたって現れる類似のコードであり、Filed注入を指す.
ex)取引、性能ログ記録等

AOPを適用すると...

これらの共通の論理,コードをモジュール化して組み合わせて開発することができる.
AOPの重要な概念
  • 調査と目標
  • Asspectはモジュールの組み合わせ
  • 対象は
  • Advice
  • モジュールでやるべきこと
  • Joint pointとPoint
  • 関節点は合流点を意味する.このオプションは、メソッド、クラス、フィールド値のいずれかのアクセスポイントおよび実行ポイントに挿入されます
  • Pointcutは、このモジュールをどこに適用するかを示す.
  • AOPの実現体
  • AOPはSpring、Javaに限定されるとは限りません.
  • 参考:https://ko.wikipedia.org/wiki/観点に向けたプログラミング
  • 仕様説明はJava、スプリングはSpring AOP(限界機能のみ)
  • AOPの適用方法
  • コンパイル時点
  • Java.classファイルにコンパイルするときに操作されるバイトコードを実行します.ロード、実行時に単独で行う必要はありませんが、単独のコンパイルプロセスが必要です.
  • ロード時間
  • ファイルロード時の織り、ロード時間織り
  • クラスロード時間を増やすにはload time weaverをJava agentに設定する必要がある
  • 複数回答対応
  • 運転時
  • Proxyオブジェクトで包み、最初のbean設定時間を増やす.
  • =コンパイル時、ロード時にAOPを適用する方法は主に「評価」で使用される
    ◆運転時にAOPを適用するのは主にSpring AOPで使用される.
    スプリングAOP:エージェントベースAOP
    スプリングAOP特性
  • ProxyベースAOP実施体
  • Spring Beanのみ適用.
  • すべてのAOP機能を提供するのではなく、Spring IoCと組み合わせて、企業アプリケーションで最も一般的な問題に解決策を提供することを目的としています.
  • Proxy Pattern
  • エージェントモードを使用する理由
  • 既存コードを変更することなくアクセス制御・付加機能を追加するため
  • クライアントは、既存のコードに触れずにインタフェースタイプのエージェントを使用することができる.
  • エージェントパターンの問題

  • 毎回プロキシカレンダーに記入します.

  • 複数のクラス、複数のメソッドに適用するには、オブジェクトとの関係が複雑になります.
    ex )
    
    // interface
    public interfaceEventService {
    
    	voidcreateEvent();
    
    	voidpublishEvent();
    
    	voiddeleteEvent();
    }
    
    // Proxy
    @Primary
    @Service
    public class ProxySimpleEventService implements EventService{
    
        @Autowired
        SimpleEventService simpleEventService;
    
        @Override
        public void createEvent() {
            long begin = System.currentTimeMillis();
            simpleEventService.createEvent();
            System.out.println(System.currentTimeMillis()-begin);
        }
    
        @Override
        public void publishEvent() {
            long begin = System.currentTimeMillis();
            simpleEventService.publishEvent();
            System.out.println(System.currentTimeMillis()-begin);
    
        }
    
        @Override
        public void deleteEvent() {
            simpleEventService.deleteEvent();
        }
    }
    
    // Real Subject
    @Service
    public class SimpleEventService implements EventService{
    
        @Override
        public void createEvent() {
            long begin = System.currentTimeMillis();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("create an evnet");
    
            // Crosscutting concern : 각 메소드 마다 공통된 모듈 
            System.out.println(System.currentTimeMillis()-begin);
        }
    
        @Override
        public void publishEvent() {
            long begin = System.currentTimeMillis();
    
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Published an event");
    
            System.out.println(System.currentTimeMillis()-begin);
        }
    
        public void deleteEvent(){
            System.out.println("Delete event");
        }
    }
  • そこでSpring APが登場
    Spring AOP
  • スプリングIoC容器が提供するインフラストラクチャと動的エージェントを用いて多くの複雑な問題を解決する.
  • 動的エージェント:エージェントオブジェクトを動的に作成する方法
  • Javaが提供する方法は、インタフェースベースのエージェントを作成すること
  • CGlibはクラスベースのエージェントをサポート
  • SpringIoC:既存のアイドルの代わりに動的エージェントを作成して登録します.
  • クライアントについてはコード変更なし.
  • AbstractAutoProxyCreatorはBeanPostProcessorを継承します.
  • https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.html
  • https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/config/BeanPostProcessor.html
  • スプリングAOP:@AOP
    動画ベーススプリング@AOP
    使用にはspring-boot-start-aop依存性が必要です
    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
     </dependency>
    ビューの定義
  • 調査は「提案」と「切り込み点」を定義する.
  • 評価として使用するクラスはbeanとして登録する.
  • @AroundプレゼンテーションアプリケーションPoint-cutを使用できます.
  • @Aspect
    @Component
    public class PerfAspect {
    
        // createEvent, publlishEvent 메소드에 적용될 aop 이다.
        // @Around에 Pointcut을 정의할 수 있다. 즉 적용시점을 정의할 수 있다.
       // @Around("execution(* me.jhjhj..*.EventService.*(..))")
       // @Around("bean(simpleEventService)")
        @Around("@annotation(PerfLogging)")
        public Object logPerf(ProceedingJoinPoint pjp) throws Throwable{
            long begin = System.currentTimeMillis();
            Object retVal = pjp.proceed();
            System.out.println(System.currentTimeMillis() - begin);
            return retVal;
        }
    
        // 메소드 실행 이전에
        @Before("bean(simpleEventService)")
        public void hello(){
            System.out.println("hello");
        }
    }
    
    // RetentionPolicy에도 다양한 스코프가 존재, 
    // RetentionPolicy.CLASS : 이 애노테이션을 class 파일까지만 적용하겠다.
    @Documented
    @Retention(RetentionPolicy.CLASS)
    public @interface PerfLogging {
    }
    Point-CUTの定義
  • @Pointcut(式)
  • 主な表現
  • execution:パケットパス(パケットパス内のすべてのオブジェクトがaopに適用される)
  • @annotation:個別のプレゼンテーション定義の後、aopとして使用したいメソッド、クラスにのみ適用されます.
  • 豆:豆名記載
  • Point-CUT組合せ
  • &&, ||, !
  • サービスの定義
  • @Before
  • @AfterReturning
  • @AfterThrowing
  • @Around
  • ✅ Spring AOP公式マニュアル:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop-pointcuts
    出典:[インフラストラクチャ講座]ホワイトベースライン-スプリングフレームワークのキーテクノロジー