AOP

박채은·2022년 12월 13일
0

Spring

목록 보기
10/35

이전에 정리한 AOP 글 참고하기

  • AOP(Aspect Oriented Programming): 관심 지향(= 공통 관심사) 프로그래밍
  • 핵심 관심 사항(Core Concerns) : 비지니스 로직, 애플리케이션의 목적을 달성하기 위한 핵심 로직에 대한 관심사
  • 공통 관심 사항/횡단 관심사(cross-cutting concerns) : 애플리케이션에서 공통적으로 사용되는 기능에 대한 관심사
    ex) 보안, 로킹, 트랜잭션, 모니터링, 트레이싱 등


출처: https://steady-coding.tistory.com/608

  • AOP는 Aspect를 통해서 다양한 기능들을 분리해서 모듈화한다.

  • 핵심 기능과 부가 기능을 분리하고, 분리된 부가 기능을 어디에 적용할지 선택한다.

  • OOP의 모듈화의 핵심 단위는 클래스이고, AOP의 모듈화의 핵심 단위는 관점(공통 관심)입니다.

  • AOP는 애플리케이션을 횡단 관심사 관점으로 보아, OOP의 부족한 부분을 보조하는 역할을 한다.

    • 트랜잭션, 보안, 로깅 등은 핵심 기능은 아니지만, 애플리케이션에 필수적인 부가 기능이다.
      그러므로 OOP만 사용하는 비즈니스 클래스에는 핵심 기능과 부가 기능이 함께 공존하게 되며 코드가 복잡해져서 파악이 어렵다.

    • 또한, 공통적으로 사용되는 부가 기능의 중복 코드가 늘어나서, 유지보수가 어렵다.


용어

  • 전체 큰 화살표 = 프로그램의 흐름
  • 화살표 내부에 조인 포인트가 존재한다.
  • 각각의 조인 포인트에 Aspect가 들어가서 실행된다.

Aspect

  • 부가 기능해당 부가 기능을 어디에 적용할지를 정의해서 모듈화한 것

  • Advice + PointCut

    • Advice: 부가 기능을 정의한 코드

    • PointCut : Advice를 어디에 적용할지 결정하는 것

  • 여러 개의 Advice + PointCut 쌍으로 구성됨

어드바이저

  • 한 쌍의 Advice + PointCut

조인 포인트

  • 애플리케이션 실행 흐름에서의 특정 포인트 = AOP를 적용할 수 있는 모든 지점
  • 조인 포인트에 Aspect 코드를 추가할 수 있다.
  • 스프링 AOP는 프록시 방식을 사용하므로, 조인 포인트는 항상 메소드 실행 지점이 된다.

프록시 : 클라이언트와 서버 사이에 존재하며, 대리로 통신을 수행해주는 컴퓨터 시스템이나 응용 프로그램

[그림] 출처 : https://ko.wikipedia.org/wiki/%ED%94%84%EB%A1%9D%EC%8B%9C_%EC%84%9C%EB%B2%84


Advice

  • 조인 포인트에서 수행되는 코드 (부가 기능)
  • Aspect를 언제 핵심 코드에 적용할 지를 정의 => when

Pointcut

  • 조인 포인트 중에서 Advice가 적용될 위치(대상)를 선택 => where
  • AspectJ 표현식을 사용해서 지정한다.
  • 프록시를 사용하는 스프링 AOP는 메서드 실행 지점만을 조인 포인트로 설정하므로, PointCut도 메서드 실행 지점만 선별한다.

타겟

  • 핵심 기능을 담고 있는 모듈 = 부가 기능을 적용할 대상
  • Advice를 받는 객체
  • Pointcut으로 결정됨

위빙(Weaving)

  • Pointcut으로 결정한 타겟의 조인 포인트에 Advice를 적용하는 것
    = 핵심 기능에 부가 기능을 적용하는 것
    = AOP가 구현되는 과정

  • 컴파일 타임
  • (클래스) 로드 타임
    • 컴파일 후, 메모리에 올라가는 시점에 AOP가 적용
  • 런타임 : 프록시 방식(Spring AOP)

Advice

  • 어드바이스는 순서를 보장하지 않는다.

Advice의 종류

조인 포인트 실행 시점을 기준으로 한다.

1. Before

  • 조인 포인트의 실행 이전에 Advice를 실행한다.
  • 일반적으로 리턴타입이 void
  • Advice 메서드에서 예외를 발생시킬 경우, 타겟 객체의 메서드가 호출되지 않는다.

2. After

2-1. After returning

  • 조인 포인트의 실행이 정상 완료된 후에 Advice를 실행

2-2. After throwing

  • 조인 포인트가 예외를 throw한 경우에, Advice를 실행

2-3. After (finally)

  • 조인 포인트 실행 결과와 상관없이 이후에 실행됨
  • 일반적으로 리소스를 해제할 때 사용함

3. Around

  • 조인 포인트의 실행 전후에 실행됨
  • Advice의 첫 번째 파라미터는 (ProceedingJoinPoint joinPoint)를 사용해야 한다.
    • joinPoint.proceed(): 조인 포인트 실행
  • 가장 강력한 어드바이스
  • 하지만 @Around만을 사용하는 것보다, 제약이 있지만 어떤 역할을 하는지 명확하게 알려줄 수 있는 @Before나 @After를 사용하는 것이 좋다.

조인 포인트

  • 메서드 실행 지점, 생성자, 필드 값 변경, static 메서드 등이 있다.

  • AspectJ를 사용한 AOP는 AOP를 모든 지점에 다 적용할 수 있다.

  • 하지만 프록시 방식을 사용하는 스프링 AOP는

    • 메서드 실행 지점에만 AOP를 적용할 수 있다.

    • 스프링 컨테이너가 관리할 수 있는 스프링 빈에만 AOP를 적용할 수 있다.

  • 조인 포인트는 Advice 메서드의 인자로 들어간다.

    • 해당 Advice는 인자를 통해, 조인 포인트의 정보를 얻는다.

Proxy 패턴

실제 기능을 수행하는 객체 대신에 가상의 객체(프록시)를 사용해서 로직의 흐름을 제어하는 디자인 패턴

스프링 AOP는 프록시 패턴을 사용한다.
원래 Java가 동적 Proxy라서 jar 실행 파일로 돌아가면 필요한 Class를 가져오는데 Spring Container로 관리되면 Class 대신 Proxy 객체를 가져온다.

  • Service와 Proxy는 동일한 인터페이스를 구현하며, Proxy에는 핵심 기능과 부가 기능이 담겨 있으며 메소드 수행 시 실제 객체(Service)의 메소드에 위임한다.

✔️ 프록시 객체를 쓰는 이유?
기존 코드의 변경없이 접근 제어 및 부가 기능을 추가하기 위해서


AOP-Proxy 방식

  • 스프링은 런타임 시에 스프링 컨테이너가 빈을 만들기 때문에 런타임 시기에만 AOP가 가능하다.

  • Spring AOP는 스프링 컨테이너에 등록된 빈에서만 사용될 수 있다.

  • 스프링 컨테이너는 Aspect의 적용 대상이 되는 객체를 생성하면서 자동으로 Proxy 객체를 같이 만든다.

    • Pointcut을 통해서 Aspect의 적용 대상이 되는지 확인함

  • 프록시는 타겟의 요청을 대신 받아주므로 타겟에 접근할 때는 프록시를 통해서 간접적으로 접근한다.
  • 프록시는 타겟 메소드 실행 전후로, 부가 기능을 실행하도록 구성된다.

✔️ 정리하자면!
스프링 컨테이너는 실행되기 전에 빈 객체를 만들면서, 해당 객체가 Aspect의 적용 대상인지 Pointcut을 통해 확인한다.
Aspect를 적용할 대상이면 프록시를 생성해주고 아니면 생성하지 않는다.
프록시 객체는 Aspect를 본인이 가로채서 객체 대신에 실행해준다.


[참고]
https://steady-coding.tistory.com/608

0개의 댓글