[Spring] 스프링 입문 - AOP

jy9922·2022년 8월 11일
0

Spring

목록 보기
11/34
post-thumbnail

✔ AOP

🔹 AOP가 필요한 상황

  • 모든 메서드의 호출 시간을 측정하고 싶다면?

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

    • 공통 관심 사항과 핵심 관심 사항을 분리해야 한다.
  • 회원 가입 시간, 회원 조회 시간을 측정하고 싶다면?

MemberService 회원 조회 시간 측정 추가

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 적용

  • AOP : Aspect Oriented Programming
  • 공통 관심 사항 (cross-cutting concern) vs 핵심 관심 사항(core concern) 분리

TimeTraceAOP

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;

@Aspect // AOP 이용하려면 @Aspect!
@Component // SpringConfig에서 Bean 등록해도 됨
public class TimeTraceAOP {

    @Around("execution(* hello.hellospring..*(..))")
    // 어디에 적용할지 설정 (파일 아래 다 적용하겠다는 의미)
    public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        System.out.println("START: " + joinPoint.toShortString());
        try {
            return joinPoint.proceed();
        } finally {
            long finish = System.currentTimeMillis();
            long timeMS = finish - start;
            System.out.println("END:" + joinPoint.toString() + " " + timeMS + "ms");
        }

    }
}
  • 회원가입, 회원 조회 등 핵심 관심사항과 시간을 측정하는 공통 관심 사항을 분리한다.
  • 시간을 측정하는 로직을 별도의 공통 로직으로 만들었다.
  • 핵심 관심 사항을 깔끔하게 유지할 수 있다.
  • 변경이 필요하면 이 로직만 변경하면 된다.
  • 원하는 적용 대상을 선택할 수 있다.

Spring AOP 동작방식

AOP 적용 전 의존관계

AOP 적용 후 의존관계

스프링은 AOP가 적용되면 가짜 memberService(프록시)를 만들고, 프록시를 호출한다.
AOP 로직(joinPoint.proceed( ))이 실행되면 진짜 memberService를 호출한다.

0개의 댓글