[SpringBoot] Spring AOP는 무엇이고 언제 써야할까?

이상훈·2021년 12월 14일
0

spring

목록 보기
2/4
post-custom-banner

📕 AOP가 필요한 상황

  • 모든 메소드의 런타임을 알고싶다면?
  • Jpa, MyBatis등 DB의 슬로우쿼리를 찾고싶다면?
  • 공통 관심 사항(cross-cutting concern) vs 핵심 관심 사항(core concern)

📕 AOP를 안쓰면 어떻게 될까?

회원 조회를 예를 들어보자.
아래의 코드를 보면 서비스단에서 회원 리포지토리를 통해 전체 회원의 목록을 가져온다.

public List<Member> findMembers() {
        return memberRepository.findAll();     
}

만약 이 메서드의 런타임을 알고싶다면 Aop를 모르는 우리는 어떻게 해야할까?

아래와 코드와 같이 System.currentTimeMillis() 메서드를 통해 시작과 종료시의 차를 이용해 처리된 시간을 구할 수 있다.

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");
	} 
}

만약 여기서 시간을 확인해야하는 메서드가 1000개가 되면 유지보수 작업은 커녕 실 개발시에 소요되는 시간도 엄청날 것이다.

이때 AOP를 적용하면 쉽게 처리할 수 있다.


📕 AOP 클래스 생성

@Component
@Aspect
public class TimeTraceAop {
	//AOP를 적용시킬 패키지 경로를 입력한다.
	@Around("execution(* com.shlee..*(..))")
	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"); 
            	}
        }
}

@Component 어노테이션을 통해 스프링컨테이너에 빈등록을 해준다.
@Aspect 어노테이션을 사용하면 비즈니스 로직 실행 전, 후에 동작하게 된다.
@Around 어노테이션을 통해 AOP가 동작할 패키지를 지정한다. (위의 코드는 모든 메서드에서 동작하게 되어있다.)

작동방식을 짚고 넘어가자면

AOP를 사용하지 않을때 컨트롤러에서 서비스의 의존성을 주입받아 호출된다.

@Aspect 어노테이션을 사용하고 AOP를 서비스단 에만 적용하게 되면 서비스 프록시를 생성하게 되고, 컨트롤러에 주입된다.

이를 통해 실제 동작시 위에 정의한 excute 메서드가 서비스 시작, 종료 시간 및 런타임을 측정할 수 있다.

profile
Hello!
post-custom-banner

0개의 댓글