AOP

14285 ワード

  • のすべてのメソッドの呼び出し時間を測定したい場合は?
  • @Transactional
    public class MemberService {
    
        private final MemberRepository memberRepository;
    
        //Dependency Injection
        //현 클래스에서 생성하는 것이 아닌 외부에서 생성한 것을 넣어주는 형태
        public MemberService(MemberRepository memberRepository) {
            this.memberRepository = memberRepository;
        }
    
        /**
         * 회원 가입
         */
        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");
            }
        }
    
        private void validateDuplicateMember(Member member) {
            memberRepository.findByName(member.getName())
                .ifPresent(m -> {
                    throw new IllegalStateException("이미 존재하는 회원입니다");
                });
        }
    
        /**
         * 전체 회원 조회
         */
        public List<Member> findMembers() {
            long start = System.currentTimeMillis();
            try {
                return memberRepository.findAll();
            } finally {
                long finish = System.currentTimeMillis();
                long timeMs = finish - start;
                System.out.println("findMembers ="+timeMs+"ms");
            }
        }
    
        public Optional<Member> findOne(Long memberId){
            return memberRepository.findById(memberId);
        }
    }
    join法とfindMembers法では時間測定のためのコードを追加した.このサービスクラスに数十、数百の方法がある場合、メンテナンスとメンテナンスはどうなりますか?
    非常に難しい
    に質問
  • 会員登録、会員照会計時機能は核心的な関心事項ではない(計時のみ)
  • 測定
  • 時間の論理は共通の関心の問題(すべての方法の時間を測定する)
  • である.
  • 時間の測定ロジックとコアトラフィックのロジックが混在しており、メンテナンスが困難である
  • 測定
  • 時間の論理を単独の汎用論理から減算して
  • を作成することは困難である.
    測定
  • 時間の論理を変更するには、各論理に対して
  • を1回変更する必要があります.

    このためにAOPを適用する

  • ビュー向けのプログラム設計観点向けのプログラム設計
  • Before

    After

    問題を共通の関心事項と核心的な関心事項に分ける


    Cross-cutting-concern VS Core-concern

    適用


    AOPのTimeTraceAOPクラスの作成
  • @Asspect(観点ガイド)
  • を記入する必要がある
  • @ComponentはBenとして登録されており、Springは
  • を管理することができます.
  • @Aroundで目的のターゲットを特定
  • 「実行(*<必要なフォルダ内のファイル>(...)」
  • "execution( hello.hellospring..(..))")
  • hello.つまりhellospringサブファイル
  • に適用される
  • JoinPointにはいくつかの方法があり、必要に応じて異なる方法を選択できます.
  • は、例えば、特定の条件下において、
  • という論理を実行しなくてもよい.
    @Aspect
    @Component
    public class TimeTraceAop {
    
    
        @Around("execution(* hello.hellospring..*(..))") //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");
            }
        }
    
    }

    結果

  • 会員加入、会員照会などの核心的な関心事項と測定時間の共通の関心事項は
  • に分かれている.
    測定
  • 時間の論理を独立した汎用論理
  • とした.
  • コアの注目点を清潔に保つ(コードを貼り付ける必要はない)
  • を変更する必要がある場合は、この論理を変更するだけです.
    選択可能
  • (@Around)
  • スプリングのAOP運動方式


    既存のスプリング依存関係からクラスを呼び出す
    ハローコントローラ----->メンバーサービス依存
    helloControllerがmemberServiceメソッドを呼び出すとmemberServiceによって呼び出されます
    AOP適用後依存関係からクラスを呼び出す
    AOPがある場合、スプリングは呼び出されたメンバーサービスの偽エージェントを作成します.では、エージェント(偽)が呼び出され、終了すると、joinPoint.preceed()が呼び出され、実際のメンバサービスが呼び出される.