본문 바로가기

WINK-(Web & App)/Spring Boot 스터디

[2025 1학기 스프링부트 스터디] 최비성 #7주차

반응형

섹션 8. AOP

AOP가 필요한 상황

요약 : 

1. 모든 메소드의 호출 시간을 측정하고 싶다면?

- 근데 회원가입, 회원 조회에 시간을 측정하는 기능은 핵심 관심 사항이 아니다. 시간을 측정하는 로직은 공통 관심 사항이다. 1000개의 메서드에 1000개의 로직 코드를 짜서 관리하기란 너무 불편하고 어지럽다.

 

2. 공통 관심 사항(cross-cutting concern) 과 핵심 관심 사항(core concern)으로 분리해서 유지보수, 관리하기 편하게 개발하자.

 

3. 그렇게 도와주는 게 AOP(Aspect Oriented Programming)다. 관점 지향 프로그래밍.

 

package hello.hellospring.service;

@Transactional
public class MemberService {
  /**
   * 회원가입
   */
  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");
    }
  }
}

 

 

 

 


AOP 적용

 

패키지, 클래스 파일 생성

 

package wink.spring_boot_study.aop;

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

@Aspect
@Component // 이렇게 해도 되고 아니면 config에서 빈 등록해서 쓰는 걸 더 선호한다.
public class TimeTraceAop {

  @Around("execution(* wink.spring_boot_study..*(..))") // 공통 관심 사항을 내가 타겟팅 할 수 있는데, spring_boot_study 패키지 내부의 모든 것에 적용을 하겠다는 설정이다.
  public Object execut(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();
  // }

ServiceConfing.java

 

 

 

AOP 적용 전 동작
AOP 적용 후 동작

 

 

AOP를 적용하면 진짜 서비스를 가지고 코드를 조작하는 게 아니라 프록시 서비스라는 이름의 복제본을 만들어서 조작한다. .AOP가 다 실행이 되고 joinPoint에 proceed()하면 그 때 진짜 멤버 서비스에 호출이 되고 막 이렇게 되는 거?다.

 

다른 방법으로는 자바에서 컴파일 타임에 코드를 아 그 제네레이터에서 자바 코드를 위아래로 박아서 넣어주는 그런 기술들도 있다고 한다. 

 

 

 

 

인프런 스프팅 입문 끝.

 

 

반응형