AOP

10351 ワード

Aspect Oriented Programming

いつ使いますか。


1000の方法があると言ってください.この時、誰かが現れて、彼にこれらの方法の呼び出し時間を知らせた.

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");
   }
 }
このように、tryfinally文の開始時、終了時に測定時間から値を減算する方法を思い出します.
でもこれなら1000回やったらいくつかの問題が発生します

  • 時間測定ロジックは,コア関心の問題(Core Concern)ではなく,共通関心の問題(Cross−cuttingConcern)であり,両者を混合するとコードの毒性が低下し,メンテナンスが困難になる.
    また,時間測定ロジックを個別のロジックに作成することは困難であり,前述したように各メソッドが完了しなければならない.
    このような状況を解決するために出てきたのはAOPです.
  • AOP

    package com.example.hellospring.aop;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.stereotype.Component;
    
    @Aspect
    public class TimeTraceAop {
    
        @Around("execution(* com.example.hellospring..*(..)) && !target(com.example.hellospring.SpringConfig)")
    //    @Around("execution(* com.example.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");
            }
        }
    }
        @Bean
        public TimeTraceAop timeTraceAop () {
            return new TimeTraceAop();
        }
    AOPという名前のパッケージを作成し、AOPを実装してコンテナに入れます.

    @Around


    Around Arnovationこのaopをどこに適用するかを指定します.
    @Around("execution(* com.example.hellospring..*(..)) && !target(com.example.hellospring.SpringConfig)")
    @Around("execution(* com.example.hellospring..*(..))")
    問題は、aroundを2つ目の方法で適用するとエラーが発生することです.
    この文章参照.

    結果



    あなたが見たように、時間の測定がよくできています!

    さぎょうげんり


    AOPの適用部分については、beanがProxybeanを作成します.Springは,呼び出しコードが操作されるProxyによって時間を計測し,JoinPointによって真のbeanを呼び出す方式である.
    詳細は別途整理する.