티스토리 뷰

반응형

Spring의 주요 특징 중하나인 AOP에 대해 알아보자

예로 아주 간단한 회원가입 웹사이트를 만든다고 해보자, 핵심 로직들은 CRUD 즉 회원가입, 조회, 수정, 삭제 등이 될 것이다

웹사이트의 핵심 로직

그런데 만약 사이트의 성능을 체크하기 위하여 각 로직들마다 수행하는데 어느 정도의 시간이 걸리는지 측정하려면

일일이 각 로직들에게 시작시간 - 끝나는 시간 등의 코드를 작성하여 뽑아야 할 것이다

하지만 이렇게 각 로직에 시간 측정이라는 기능을 넣게 되면, 유지 보수가 힘들 뿐만 아니라

본래 기능에 다른 기능이 들어오기 때문에 객체 지향의 핵심 원칙 중 하나인 SRP에도 어긋나게 된다

 

이때 각 로직이 공통으로 가지고 있는 기능(관심사)을 하나로 묶어서 실행시켜 준다면?

이를 가능하게 하는 것이 바로 AOP이다

 

AOP(Aspect Oriented Programming)

Spring의 DI가 각각의 로직을 분리시켜 모듈들 간의 결합도를 낮춰준다면 AOP는 반대로 흩어져 있던 모듈들은 한데 모은다

즉 각 로직에 공통적으로 있던 시간 측정이라는 "공통 관심사"를 한 번에 묶어 실행시킬 수 있게 해 준다 보통 이를 "모듈화"라고 부른다

AOP를 구성하는 핵심 개념들은 아래와 같다

• Aspect (공통 관심사를 모듈화 한 것)

• Target (Aspect를 적용할 곳)

• Advice (실질적으로 어떤 부가기능을 담고 있는지)

• JointPoint (Advice가 적용될 위치)

• PointCut (JointPoint의 실행할 지점을 더욱 구체적으로 정의)

 

적용 예시
implementation 'org.springframework.boot:spring-boot-starter-aop'

우선 Gradle에 aop를 받아올 수 있도록 해주었다 (Maven에 경우 pom.xml에서 작업)

@Component
@org.aspectj.lang.annotation.Aspect
public class Aspect {

    @Around("execution(* hello.core..*(..))")
    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 클래스를 하나 만들어서 빈으로 등록하고

Around Advice로 작성하여 시간 측정을 할 수 있게끔 간단하게 예시를 만들었다

START: execution(MemberService hello.core.order.AppConfig.memberService())
START: execution(MemberRepository hello.core.order.AppConfig.MemberRepository())
END : execution(MemberRepository hello.core.order.AppConfig.MemberRepository())1ms
END : execution(MemberService hello.core.order.AppConfig.memberService())28ms
START: execution(OrderService hello.core.order.AppConfig.orderService())
START: execution(DiscountPolicy hello.core.order.AppConfig.discountPolicy())
END : execution(DiscountPolicy hello.core.order.AppConfig.discountPolicy())1ms
END : execution(OrderService hello.core.order.AppConfig.orderService())3ms

이후 스프링을 실행시키면 내가 적용했던 메서드들이 실행될 때 AOP가 따로 호출되어서 시간을 측정한 결과를 볼 수 있었다

 

더보기

개인 학습을 위해 작성되는 글입니다.

제가 잘못 알고 있는 점에 대한 지적 / 더 나은 방향에 대한 댓글을 환영합니다.

 

참조 링크:

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard

 

 

참조 서적:

스프링 입문을 위한 자바 객체지향의 원리와 이해 - 김종민 저

 

 

 

반응형
댓글