Programming/Spring

[Spring/스프링] AOP(Aspect Oriented Programming) 이해하기

예민한고라니 2022. 3. 6. 18:49

AOP가 뭔가요?

  • AOP를 설명하기 전, 한가지 상황을 예시로 들어보자.
    /**
     * 회원가입 메소드
     */
    public Long join(Member member){
        validateDuplicateMember(member);
        memberRepository.save(member);
        return member.getId();
    }
  • 위와 같은 회원가입, 회원 조회 등, 1000개의 메소드로 이루어진 회원 관리 프로그램이 있다.
  • 모종의 이유로 회원관리 프로그램에서 모든 메소드의 호출시간과 종료시간을 측정해야 한다고 가정해보자
    /**
     * 회원가입 메소드
     */
    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");
       }
    }
  • 우리는 프로그램에 존재하는 모든 메소드에 위와 같이 시간을 측정하는 코드를 추가해야한다!
  • 1000번의 반복끝에 어렵게 구현했지만.. 누군가가 "초단위로 구하도록 수정해줘!" 라고한다면? 아마 우리는 똑같은 작업을 1000번 더 해야할것이다.
  • 이를 해결하기 위해 등장한 것이 바로 AOP 란 개념!

 

좀 더 자세히 설명해주세요!

  • AOP는 Aspect Oriented Programming의 약자로 관점 지향 프로그래밍 이라 부른다.
  • 즉 어떤 로직을 공통 관심 사항핵심 관심 사항 두가지 관점으로 나누어 각각 모듈화 하겠다는 의미
  • 앞 선 예시에서는, 회원가입, 회원조회 등이 핵심 관심사항이 되고, 시간을 측정하는 것이 공통 관심 사항이 되는 것
  • 공통 관심 사항과 핵심 관리 사항 두가지를 분리하여 로직을 짜게 되면, 앞선 예제처럼 공통 관심사항의 내용 변경이 필요할때, 모든 각각의 메소드들을 직접 수정을 하는것이 아닌 공통된 로직만을 수정하면 된다!

 

  • 아래는 AOP를 활용하여, 공통 관심 사항인 시간 측정 로직을 따로 만들어 준 것이다.

 

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는 이걸 적어줘야 쓸 수 있음
@Component
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");

        }
    }
}
  • aop라는 하위 패키지를 만들고 위와 같은 클래스를 만들어 줌으로써, 특정 패키지 하위에 있는 모든 메소드에 적용할 수 있는 시간 측정 기능을 만들 수 있다!

 

AOP는 어떻게 동작 되나요?

  • 아래는 AOP 적용전의 스프링 컨테이너 동작이다.

  • 스프링 컨테이너는 Controller와 service사이의 이런 의존관계가 있음을 알고 memberService를 호출하는 역할을 수행한다.

  • AOP를 사용할 경우, AOP에 적용되는 서비스 실행 이전 스프링은 프록시(Proxy) 라 부르는 가짜 memberService를 만들어 세워 놓는다
  • 이후 가짜 스프링빈이 끝나고 joinPoint.proceed()를 통해 진짜 memberService를 호출해주게 된다.
  • 정리하자면, Controller가 호출하는 것은 프록시라는 기술로 인해 발생하는 memberService 인것이다

 


해당 게시글은 인프런 - 김영한 님의

[스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술] 강의에 기반합니다

 

 

[무료] 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다., - 강의 소개 | 인프런...

www.inflearn.com