Spring AOP (개념, 용어, 원리, 포인트컷 표현식, JoinPoint API)

2021. 3. 22. 03:20 Spring Framework/Spring Core

1. AOP란?

Aspect Oriented Programming 의 약자로 관점지향 프로그래밍이라고 부른다. IoC가 낮은 결합도와 관련된 것이라면 AOP 는 높은 응집도와 관련되어 있다.

서비스들의 비즈니스 메소드들은 복잡한 코드로 구성되어있는데, 그 중 핵심 로직은 얼마안되고 대부분은 트랜잭션, 로깅 처리, 인증과 관련된 코드들이 있을 수 있다. 이럴 때 비핵심이지만 꼭 필요하고, 공통화할 수 있는 부분을 따로 빼서(횡단 분리) 관리하는 것이다.

2. AOP 용어

  • 조인포인트(Joinpoint) : 클라이언트가 호출하는 모든 비즈니스 메소드, 조인포인트 중에서 포인트컷되기 때문에 포인트컷의 후보로 생각할 수 있다.
  • 포인트컷(Pointcut) : 특정 조건에 의해 필터링된 조인포인트, 수많은 조인포인트 중에 특정 메소드에서만 횡단 공통기능을 수행시키기 위해서 사용한다.
    • 표현식 : 리턴타입 패키지경로 클래스명 메소드명(매개변수)
  • 어드바이스(Advice) : 횡단 관심에 해당하는 공통 기능의 코드, 독립된 클래스의 메소드로 작성한다.
    • 어드바이스의 동작 시점
      동작시점 설명
      Before 메소드 실행 전에 동작
      After 메소드 실행 후에 동작
      After-returning 메소드가 정상적으로 실행된 후에 동작
      After-throwing 예외가 발생한 후에 동작
      Around 메소드 호출 이전, 이후, 예외발생 등 모든 시점에서 동작
  • 위빙(Weaving) : 포인트컷으로 지정한 핵심 관심 메소드가 호출될 때, 어드바이스에 해당하는 횡단 관심 메소드가 삽입되는 과정을 의미한다. 이를 통해 비즈니스 메소드를 수정하지 않고도 횡단 관심에 해당하는 기능을 추가하거나 변경이 가능해진다.
  • 애스팩트(Aspect) : 포인트컷과 어드바이스의 결합이다. 어떤 포인트컷 메소드에 대해 어떤 어드바이스 메소드를 실행할지 결정한다.

3. AOP 원리

작성중..

4. 포인트컷 표현식

포인트컷을 이용하면 어드바이스 메소드가 적용될 비즈니스 메소드를 정확하게 필터링할 수 있다.

4-1. 지시자(PCD, AspectJ pointcut designators)의 종류

몇가지들이 있다. 아래에선 execution 을 사용한 표현식에 대해 알아본다.

  1. execution : 가장 정교한 포인트컷을 만들수 있다. 리턴타입 패키지경로 클래스명 메소드명(매개변수)
  2. within : 타입패턴 내에 해당하는 모든 것들을 포인트컷
  3. bean : bean이름으로 포인트컷

4-2. 리턴타입 지정

표현식 설명
* 모든 리턴타입 허용
void 리턴타입이 void인 메소드 선택
!void 리턴타입이 void가 아닌 메소드 선택

4-3. 패키지 지정

표현식 설명

com.devljh.domain

정확하게 com.devljh.domain 패키지만 선택

com.devljh.domain..

com.devljh.domain 패키지로 시작하는 모든 패키지 선택

4-4. 클래스 지정

표현식 설명
UserBO 정확하게 UserBO 클래스만 선택
*BO 이름이 BO로 끝나는 클래스만 선택
BaseObject+ 클래스 이름 뒤에 '+'가 붙으면 해당 클래스로부터 파생된 모든 자식 클래스 선택, 인터페이스 이름 뒤에 '+'가 붙으면 해당 인터페이스를 구현한 모든 클래스 선택

4-5. 메소드 지정

표현식 설명
*(..) 모든 메소드 선택
update*(..) 메소드명이 update로 시작하는 모든 메소드 선택

4-6. 매개변수 지정

표현식 설명
(..) 모든 매개변수
(*) 반드시 1개의 매개변수를 가지는 메소드만 선택

(com.devljh.domain.user.model.User)

매개변수로 User를 가지는 메소드만 선택. 꼭 풀패키지명이 있어야함

(!com.devljh.domain.user.model.User)

매개변수로 User를 가지지않는 메소드만 선택

(Integer, ..) 한 개 이상의 매개변수를 가지되, 첫 번째 매개변수의 타입이 Integer인 메소드만 선택
(Integer, *) 반드시 두 개의 매개변수를 가지되, 첫 번째 매개변수의 타입이 Integer인 메소드만 선택

5. JoinPoint 인터페이스

어드바이스 메소드를 의미있게 구현하려면 클라이언트가 호출한 비즈니스 메소드의 정보가 필요하다. 예를들면 예외가 터졌는데, 예외발생한 메소드의 이름이 뭔지 등을 기록할 필요가 있을 수 있다. 이럴때 JoinPoint 인터페이스가 제공하는 유용한 API들이 있다.

메소드 설명
Signature getSignature() 클라이언트가 호출한 메소드의 시그니처(리턴타입, 이름, 매개변수) 정보가 저장된 Signature 객체 리턴
Object getTarget() 클라이언트가 호출한 비즈니스 메소드를 포함하는 비즈니스 객체 리턴
Object[] getArgs() 클라이언트가 메소드를 호출할 때 넘겨준 인자 목록을 Object 배열 로 리턴

Signature API

메소드 설명
String getName() 클라이언트가 호출한 메소드 이름 리턴
String toLongString() 클라이언트가 호출한 메소드의 리턴타입, 이름, 매개변수(시그니처)를 패키지 경로까지 포함 하여 리턴
String toShortString() 클라이언트가 호출한 메소드 시그니처를 축약한 문자열로 리턴

사용법

JoinPoint를 어드바이스 메소드 매개변수로 선언해야한다. 이때 인자는 스프링 컨테이너가 넘겨준다. ex. 메소드명(JoinPoint jp)

이때 Around 어드바이스만 다른 어드바이스와 약간 다른데, ProceedingJoinPoint 객체를 인자로 선언해야한다.(proceed() 등이 추가로 구현되어있음) ProceedingJoinPoint 는 JoinPoint를 상속받는다.



출처: https://sjh836.tistory.com/157?category=680970 [빨간색코딩]