본문 바로가기
Spring

[Spring] AOP가 필요한 이유, AOP 용어 / Advice, Pointcut, JointPoint

by jungha_k 2022. 10. 18.

 

 

[Spring] AOP란? (Aspect Oriented Programming)

AOP (Aspect Oriented Programming)란? = 관심(Aspect) 지향 프로그래밍 AOP에서 말하는 관심 = 애플리케이션에 필요한 기능 중 공통적으로 적용되는 기능에 대한 관심 공통 관심 사항 & 핵심 관심 사항? 공통

wlikeoxy.tistory.com

에 대한 추가 공부


관점 지향 프로그래밍 = AOP(Aspect Oriented Programming)

: Aspect를 사용하여 다양한 기능들을 분리한다.

 

(* Aspect? : 하나의 모듈! = 부가 기능해당 부가 기능을 어디에 적용할 지 정의한 것)

   Aspect =                              Advice   +                     PointCut

 

 

OOP와 대척되는 개념이 아님!

오히려 OOP의 부족한 부분을 보조하는 목적으로 사용됨

횡단 관심사(전체를 관통하는 공통 관심사)를 깔끔하게 처리하기 위함

 


AOP가 필요한 이유

 

이 사진 하나로 끝!

 

'객체' 중심 프로그래밍 - OOP : 정의된 기능들을 재사용 하기 위해 등장했다.

 

OOP의 핵심은 공통된 목적을 띈 데이터와, 동작을 묶어 '하나의 객체'로 정의하는 것이다.

객체를 잘 활용하기 위해서는 관심사 분리(SoC) 디자인 원칙을 준수해야 한다.

 

그런데 여러 객체들이 만들어지다 보니 

특정 객체에 공통적으로 들어가는 부가 기능들이 존재하게 된 것이다.

ex)  트랜잭션, 보안, 로깅 기능 등..

 

 

 

핵심 기능(Core Concerns) : 객체가 제공하는 고유 기능(업무 로직)

 

횡단 관심사'(Cross-cutting Concerns, 부가기능)

: 업무와는 관련이 없지만 애플리케이션에는 필수적인 부가 기능들

핵심 기능을 보조하기 위해 제공되는 기능 (단독 사용 X)

 

 

여러 비즈니스 클래스들에 이 부가 기능들이 각각 포함되어 있다보니

  • 메소드 복잡성 증가 ➡ 비즈니스 코드 파악 어려움
  • 부가 기능 불특정 다소 메소드 반복 구현 ➡ 횡단 관심사의 모듈화가 어려움

 

이러한 이유 때문에

부가 기능들을 아예 따로 떼내어서 모듈화 한 것이 바로 AOP 이다! 

= OOP 방식의 불필요한 반복을 해결

 

AOP를 사용하면

 

비즈니스 코드들에 반복적으로 부가 기능 코드를 넣지 않아도 되고, (중복 코드 제거)

부가 기능의 변경 지점도 한 곳으로 잘 관리될 수 있다. (수정 용이)

 


AOP 용어 및 개념들

 

 

애스펙트 (Aspect)

: 여러 객체에 공통으로 적용되는 기능 (애플리케이션 횡단 기능)

 

어드바이스 + 포인트컷 을 모듈화

(부가 기능) + (해당 부가 기능을 어디에 적용할 지) 

 

 

조인 포인트 (join point)

S : 메서드 실행 전의 포인트

E : 메서드 수행 후의 포인트

 

조인포인트 : S, E와 같이 어드바이스가 적용될 포인트

 

애플리케이션 실행 흐름에서의 특정 포인트

(클래스 초기화, 객체 인스턴스화, 메소드 호출, 필드 접근, 예외 발생 등)

 

메소드 실행 지점

 

 

어드바이스 (Advice) 

: 조인포인트에서 수행되는 코드

: Aspect를 언제 핵심 코드에 적용할지 정의

 

 

포인트컷 (Pointcut)

 

: 조인 포인트 중에서 어드바이스(수행되는 코드)가 적용될 위치를 선별

 

 

위빙 (Weaving)

 

: 어드바이스를 핵심 코드에 적용하는 것

핵심 기능 코드에 영향 X, 부가 기능 추가 가능

 

 

AOP 프록시 (proxy)

 

: AOP 기능을 구현하기 위해 만든 프록시 객체

출처 : 김영한님 스프링 입문 강의

 

 

타겟 (Target)

 

: 핵심 기능을 담고 있는 모듈

= 부가 기능을 부여할 대상!

 

Advice를 받는 객체, 포인트 컷으로 결정 됨

 

 

어드바이저 (Advisor)

: 1 어드바이스 + 1 포인트 컷

 

 


타입별 Advice

어드바이스 Advice

: Aspect를 언제 핵심 코드에 적용할지 정의

 

특정 조인 포인트에서 애스펙트에 의해 취해지는 조치

 

 

Advice 종류

 

  • Before

: 조인 포인트 실행 이전에 실행

@Before("hello.aop.order.aop.Pointcuts.orderAndService()")
public void doBefore(JoinPoint joinPoint) {
    log.info("[before] {}", joinPoint.getSignature());
}

 

 

  • After returning

: 조인 포인트 정상 완료 실행

@AfterReturning(value = "hello.aop.order.aop.Pointcuts.orderAndService()", returning = "result")
public void doReturn(JoinPoint joinPoint, Object result) {
    log.info("[return] {} return={}", joinPoint.getSignature(), result);
}

 

  • After throwing

: 메서드 예외 던지는 경우에 실행

@AfterThrowing(value = "hello.aop.order.aop.Pointcuts.orderAndService()", throwing = "ex")
public void doThrowing(JoinPoint joinPoint, Exception ex) {
    log.info("[ex] {} message={}", joinPoint.getSignature(), ex.getMessage());
}

 

  • After (finally)

: 조인 포인트 동작과는 상관없이 실행

 

 

  • Around

: 가장 강력한 어드바이스

인 포인트 실행 여부 선택, 반환 값 변환, 예외 변환 등 모든 기능 수행 가능

 

* 타겟 등 고려해야 할 사항이 있을 때 정상적으로 작동 안될 수도.

but Around를 사용해서 모두 해결하기 보다는 

역할을 명확하게 설계 하는 것이 Good.

 

 


Pointcut 표현식

포인트 컷 : 관심 조인 포인트를 결정 ➡ 어드바이스 실행 시기 제어할 수 있음 

 

Aspect J pointcut expression -> AspectJ 포인트컷 표현식

 

ex)

@Pointcut("execution(* transfer(..))") // 포인트컷 표현식
private void anyOldTransfer() {} // 포인트컷 서명

 

 

포인트 컷 지시자 

: 포인트컷 표현식에서 '포인트컷 지시자'로 시작함 ex) execution

 

* execution : 메서드 실행 조인트 포인트를 매칭한다.
스프링 AOP에서 가장 많이 사용하며, 기능도 복잡하다.

 

 

포인트 컷 표현식 

 

ex) AccountService 인터페이스에 의해 정의된 모든 메소드의 실행

execution(* com.xyz.service.AccountService.*(..))

 

 

포인트 컷 결합

 

: &&, ||, ! 를 사용하여 결합 가능하다

이름으로 참조할 수도 있다.

 


 

JointPoint  조인 포인트

: AOP 적용 위치(지점) - 추상적인 개념임


= 프로그램 실행 중 지점 = ex) 어드바이스가 적용될 수 있는 위치, 메소드 실행, 생성자 호출, 필드 값 접근, static 메서드 접근 등

  • AspectJ를 사용해서 컴파일 시점과 클래스 로딩 시점에 적용하는 AOP :
    바이트코드를 실제 조작하기 때문에 해당 기능을 모든 지점에 다 적용할 수 있습니다.
  • 프록시 방식을 사용하는 스프링 AOP : 메서드 실행 지점에만 AOP를 적용할 수 있습니다.
  • 프록시는 메서드 오버라이딩 개념으로 동작합니다.
  • 생성자나 static 메서드, 필드 값 접근에는 프록시 개념이 적용될 수 없습니다.
  • 프록시를 사용하는 스프링 AOP의 조인 포인트는 메서드 실행으로 제한됩니다.
  • 프록시 방식을 사용하는 스프링 AOP는 스프링 컨테이너가 관리할 수 있는 스프링 빈에만 AOP를 적용할수 있습니다.
  • JoinPoint 메소드는 어드바이스의 종류에 따라 사용방법이 다소 다르지만 기본적으로 어드바이스 메소드에 매개변수로 선언만 하면 됩니다.

 

 

 


* 이미 너무 많은 개념으로 인해 세부사항 생략된 부분😵 : 

  • execution 외에 언급된 포인트컷 지시자 종류
  • 일반적인 pointcut 표현식들
  • JoinPoint 인터페이스의 주요 기능 

추후에 프로젝트에 AOP 개념 적용시에 더 깊게 공부할 것,,

 

댓글