AOP

김슬기·2022년 9월 30일
0

AOP란?

Aspect Oriented Programming의 약자로 관점 지향 프로그래밍이라고 불린다. 관점 지향은 쉽게 말해어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화하겠다는 것이다.

AOP가 필요한 상황

  • ex) 모든 메서드의 호출시간을 측정하고싶을때

  • 공통관심사항 vs 핵심 관심 사항이 구분된다.

  • 회원 가입 시간, 회원 조회 시간을 측정하고 싶을때

  • 만약 하나의 로직을 수정해야한다면?? 모든걸 다 들어가서 메서드들을 수정해줘야 한다.

  • 예를들어서, join 메서드의 시간을 측정하고싶으면 이렇게 작성하면된다

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");
    }
}
  • 하지만, 다른메서드들도 시간측정하고 싶을때 어찌할 방도가없다
  • 다 하나하나 코드를 짜줘야하는데 굉장히 비효율적
  • 문제사항
    • 회원가입, 회원조회에 시간을 측정하는 기능은 핵심관심사항이 아님
    • 시간을 측정하는 로직은 공통관심사항이다.
    • 시간을 측정하는 로직과 핵심 비지니스의 로직이 섞여서 유지보수가 어렵다.
    • 시간을 측정하는 로직을 별도의 공통 로직으로 만들기 때문에 매우 어렵다.
    • 시간을 측정하는 로직을 변경할때 모든 로직을 찾아가면서 변경해야한다. >>매우 비효율적

AOP적용

  • 공통 관심 사항과 핵심 관심 사항을 분리한다.

  • 이전 그림과는 다르게 AOP를 이용하여 로직을 따로 작성하여 적용

  • AOP는 @Aspect 애노테이션을 클래스에 적용시켜야 사용 가능

  • aop/TimeTraceAop안에 작성

package hello.hellospring.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;

@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(); // proceed하면 다음 메서드로 진행
        } finally {
            long finish = System.currentTimeMillis();
            long timeMs = finish - start;
            System.out.println("End: " + joinPoint.toString() + " " + timeMs + "ms");
        }
    }
}
@Bean                //SpringConfig에 스프링 빈 등록 // 그냥 TimeTraceAop에 컴포넌트                                                애노테이션 하나 넣는걸로 해도 된다.
public TimeTraceAop timeTraceAop(){
   return new TimeTraceAop();
} 
  • 해결

    • 회원가입,회원 조회 등 핵심 관심사항과 시간을 측정하는 공통관심사항(시간측정)을 분리한다.
    • 시간을 측정하는 로직을 별도의 공통로직으로 만듬 >> AOP이용
    • 핵심관심사항은 건드리지않고 깔끔하게 유지
    • 변경이 필요하면 이 로직만 변경하면 OK
    • 원하는 적용 대상을 선택할 수 있다
  • AOP동작 방식 설명

    • AOP적용 전 의존관계

    • AOP 적용 후 의존관계

      • 스프링이 가짜 멤버서비스라는 프록시라는 기술로 가짜를 만들어낸다.
      • 해당하는 진짜 스프링 빈 말고 가짜 스프링빈을 실행시키고 joinPoint.proceed()를 통해 진짜 스프링 빈을 실행시킨다.
profile
낭만그리고김슬기

0개의 댓글