스프링 입문 Section7. AOP

Bae YuSeon·2024년 4월 29일
0

spring스터디

목록 보기
7/15
post-thumbnail

1. AOP가 필요한 상황

7.1)AOP가 필요한 상황

  • 모든 메소드의 호출 시간을 측정하고 싶을 때
  • 공통 관심 사항(cross-cutting concern) vs 핵심 관심 사항(core concern)
  • 회원 가입 시간, 회원 조회 시간을 측정하고 싶다면?
    aop가 필요한 상황

7.2)MemberService 회원 조회 시간 측정 추가

java/hello/hellospring/service/MemberService.java 파일에 회원 가입에 걸리는 시간, 회원 조회에 걸리는 시간을 측정하는 기능을 추가한다.

    // 회원가입
    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");
        }
    }
    
    //전체 회원 조회
    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");
        }
    }
  • join(Member member) 메서드
    • System.currentTimeMillis()를 사용하여 메서드 실행 시작 시간을 기록
    • finally 블록에서 메서드 실행 종료 시간을 기록하고, 실행 시간을 출력
  • findMembers() 메서드
    • System.currentTimeMillis()를 사용하여 메서드 실행 시작 시간을 기록
    • finally 블록에서 메서드 실행 종료 시간을 기록하고, 실행 시간을 출력

7.3)시간 측정의 문제

  • 회원가입, 회원 조회에 시간을 측정하는 기능은 핵심 관심 사항이 아니다.
  • 시간을 측정하는 로직은 공통 관심 사항이다.
  • 시간을 측정하는 로직과 핵심 비즈니스의 로직이 섞여서 유지보수가 어렵다.
  • 시간을 측정하는 로직을 별도의 공통 로직으로 만들기 매우 어렵다.
  • 시간을 측정하는 로직을 변경할 때 모든 로직을 찾아가면서 변경해야 한다.

⇒ 이러한 문제들을 해결하기 위해 AOP를 사용!

2. AOP 적용

2.1) AOP 적용

AOP: Aspect Oriented Programming

  • 공통 관심 사항(cross-cutting concern) vs 핵심 관심 사항(core concern) 분리

2.2) 시간 측정 AOP 등록

aop pacakge를 만들고 그 아래 java/hello/hellospring/aop/TimeTraceAop.java 파일을 만든다.

package hello.hellospring.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Component
@Aspect

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");
        }
    }
}
  • 스프링 빈으로 등록하기
  1. @Component 쓰기
  2. 스프링 빈에 직접 등록해서 사용
    @Bean
     public TimeTraceAop timeTraceAop(){
         return new TimeTraceAop();
     }
  • 공통 관심사항 타겟팅
    • @Around 어노테이션을 사용하여 Advice를 정의

      Advice는 실제로 메서드의 실행 전/후에 적용되는 코드

    • @Around("execution(* hello.hellospring..*(..))") 에서 Pointcut을 정의.

      Pointcut은 Advice를 적용할 메서드를 선택하는 기준을 제공

    • 이 코드에서는 hello.hellospring 패키지 및 하위 패키지에 있는 모든 메서드에 Advice를 적용하도록 설정

이후에 java/hello/hellospring/service/MemberService.java 파일에 추가했던 시간 측정 기능 코드를 삭제해 준다.

시간 측정 AOP 실행
aop 실행
실행을 하면 위 사진처럼 메서드마다 실행 시간을 알 수 있게 된다.

2.3) 스프링의 AOP 동작 방식 설명



1. AOP를 적용하면, 가짜 memberService라는 프록시 생성. 이 프록시는 실제 memberService와 동일한 인터페이스를 구현
2. 진짜 memberService 앞에 가짜 memberService를 spring bean으로 등록
3. memberController가 호출하는 경우, 실제로는 가짜 memberService 프록시가 호출
3. 가짜 memberService가 종료되면 joinPoint.proceed() 를 통해 실제 memberService를 호출.
⇒ memberController가 호출해주는 건 진짜 memberService가 아니라 가짜 memberService!

0개의 댓글

관련 채용 정보