본문 바로가기

Java and Spring

[Spring] 스프링 AOP

지금까지는 순수하게 AOP를 사용하기위해 스프링에서 무엇을 제공하고 어떤 개념을 알아야 하는지 공부했다면, 이번 포스팅에서는 스프링 AOP에대한 사용방법을 상세하게 알아보려고 합니다.

AOP란?

결론부터 말씀드리자면, AOP는 핵심적인 기능과 부가적인 기능을 분리하는데에 그 목적이 있습니다.

예를들어서 OrderService클래스의 주문을 하는 로직이 있다고 가정합니다.

그리고 주문을 할때마다 로그를 볼 수 있는 기능을 넣는다면, 아래와 같은 이미지가 될 것입니다.

그런데 이러한 부가기능을 모든 클래스에서 사용되고 있다면????

아래와 같은 그림이 될 것입니다.

사실 부가 기능이 모든 클래스가 들어가게 된다면, 반복되는 코드가 추가되고 핵심 기능과 부가 기능이 분리되지 않기때문에 유지보수 측면에서 굉장히 비효율적입니다. 또한, 부가 기능의 수정이 일어나게 된다면 모든 클래스를 찾아서 수정해야 하는 대참사가 일어나기도 합니다.

AOP는 이러한 횡단 관심사(부가 기능)를 핵심 기능에서 어떻게하면 분리할 수 있을지 고민하다가 만들어진 개념이라고 생각하시면 됩니다.

 

AOP 용어 정리

애스팩트

@Aspect는 스프링의 Pointcut과 Advice를 합친 Advisor와 같은 개념이라고 할 수 있습니다.

간단하게 요약하면, 부가 기능과 구현한 부가 기능을 어디에 적용할지 선택하는 기능을 합하여 모듈로 만들었는데 그것이 바로 애스팩트입니다.

참고로 @Aspect가 선언되어 있으면 스프링의 자동 프록시 생성기가 @Aspect를 Advisor로 변환해준다고 합니다.

 

조인포인트

조인포인트는 AOP가 적용 될 수 있는 모든 위치를 의미합니다.

예를들어 메소드 실행, 생성자 호출, 필드값 접근, static메소드 접근과 같은 프로그램이 실행 될 수 있는 모든 지점이 조인포인트로 사용될 수 있지만, 스프링 AOP는 프록시 방식을 사용하기 때문에 메소드 실행 시점에만 조인포인트를 적용 할 수 있습니다.

참고로 메소드 실행 시점을 제외한 나머지 지점에 조인포인트를 적용하고 싶다면, AspectJ프레임워크를 공부해 보시면 될 것 같습니다.

 

포인트컷

조인포인트 중에서 Advice가 적용될 위치를 정규표현식으로 정의하는 기능입니다.

포인트컷도 마찬가지로 스프링 AOP는 프록시 방식을 사용하기 때문에 메소드 실행 시점에만 포인트컷으로 적용될 위치를 선별 할 수 있습니다.

포인트컷은 여러개의 포인트컷 지시자가 존재하는데 그 중 몇가지만 알아보도록 하겠습니다.

  • execution : 여러가지 조건(접근제어자, 반환타입, 선언타입, 메서드, 파라미터, 예외)을 조합하여 만들 수 있는 가장 세심한 지정자입니다.

execution문법을 자세히 보면 execution(접근제어자? 반환타입 선언타입?메서드이름(파라미터) 예외?) 형식으로 구성되어 있는데, 중간 중간 들어가있는 "?"는 생략이 가능하다는 의미입니다.

 

선언타입은 일종의 패키지로 받아들일 수 있는데 . , ..의 차이를 명확하게 이해해야 합니다.

. : 정확하게 해당 위치의 패키지

.. : 해당 위치의 패키지와 그 하위 패키지도 포함

@Around("execution(* jpabook.jpashop.service..*(..))")

간단하게 execution지시자의 사용법을 보면 아래와 같습니다.

execution(* jpabook.jpashop.service..*(..)) => 포인트컷 지정자

execution(* jpabook.jpashop.service..*(..)) => 모든 반환타입 허용

execution(* jpabook.jpashop.service..*(..)) => jpabook.jpashop.service 하위패키지의 모든 메소드 허용

execution(* jpabook.jpashop.service..*(..)) => 모든 파라미터 혹은 모든 타입을 허용

 

  • within : 패키지내의 모든 메서드에 적용할때 사용하는 지정자입니다.
  • args : 메서드로 넘어온 파라미터의 인스턴스와 매칭되는 지정자입니다.
  • @annotation : 주어진 어노테이션을 가지고있는 곳에 매칭하는 지정자입니다.

 

어드바이스

어드바이스는 부가기능 그 자체를 의미하고 5가지 종류가 존재합니다.

  • @Around : 메서드 호출 전후에 실행하고, 개발자가 제어 할 수 있는 강력한 어드바이스라고 생각하시면 됩니다. ProceedingJoinPoint.proceed()메서드를 사용하여 다음 타겟을 호출합니다.
  • @Before : 조인 포인트(타겟 메서드) 실행 이전에 실행하고, ProceedingJoinPoint.proceed()메서드를 사용하지 않아도 자동으로 다음타겟이 호출됩니다.
  • @AfterReturning : 조인 포인트(타겟 메서드)가 정상적으로 완료후에 실행
  • @AfterThrowing : 메서드가 예외를 던지는 경우 실행
  • @After : 메서드의 실행 결과(성공, 실패)에 상관없이 실행(finally)

 

타겟

부가기능을 받는 객체를 의미하는데, 그 타겟은 포인트컷으로 결정됩니다.

 

위빙

포인트컷으로 결정된 조인포인트에 어드바이스를 적용하는 것을 의미합니다.

'Java and Spring' 카테고리의 다른 글

[Spring] 커넥션 풀과 데이터소스  (0) 2022.04.19
[Java] Message Digest 암호화 방식  (0) 2021.12.22
[Spring] 빈 후처리기  (0) 2021.12.11
[Spring] 프록시 팩토리  (0) 2021.12.08
[Java] CGLIB(Code Generator Library)  (0) 2021.12.04