Spring AOP(Aspect Oriented Programming)란?

현주·2023년 6월 20일
1

✏️ [OOP] 객체 지향 프로그래밍 (Object Oriented Programming)

  • 실제 사물을 프로그래밍으로 옮겨와 모델링하는 것

    사물 (Object) = 속성 (Variable) + 행위 (Method)

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

  • 기능을 재사용할 수 있는 것이 큰 장점

  • 관심사 분리 (Separation of Concerns, SoC)의 디자인 원칙을 준수해야함

  • OOP 모듈화의 핵심 단위 ➜ 클래스

✔ OOP의 문제점

비즈니스 클래스에 횡단 관심사와 핵심 관심사가 공존하게 되는데,
이 때 메소드 복잡도가 증가하여 비즈니스 코드 파악이 어렵고,
부가 기능의 불특정 다수 메소드가 반복적으로 구현되어 횡단 관심사의 모듈화가 어려움

👉 OOP의 관심사 분리에 대한 한계를 해결하고자 AOP 등장

✔️ 핵심 관심사 ( Core Concerns )

  • 핵심 기능
  • 객체가 제공하는 고유의 기능

    Ex. 결제 기능, 알림 기능 등

✔️ 횡단 관심사 ( Cross-cutting Concerns )

  • 핵심 기능을 보조하기 위해 여러 클래스에 걸쳐 공통으로 사용되는 부가 기능
    ➜ 중복 코드 생김 ( AOP 방식으로 해결 )
  • 핵심 기능과 함께 사용 ( 단독 X )

    Ex. 로깅, 보안, 트랜잭션, 로그 추적 로직 등

✔️ SoC ( Separation of Concerns )

  • 컴퓨터 프로그램을 구별된 부분으로 분리시키는 디자인 원칙
  • 하나의 모듈에서 여러가지의 관심사를 가지고 처리하면 복잡성이 높으니,
    관심사를 여러개로 분리하여 하나의 관심사는 하나의 기능을 가지도록 구성하는 것

✔️ 모듈 ( Module )
➜ 특정 기능별로 나누어지는 프로그램 덩어리

📌 객체 지향 프로그래밍 (OOP) 관련 포스팅


✏️ [AOP] 관점 지향 프로그래밍 (Aspect-Oriented Programming)

  • 기존과 다른 프로그램 구조 사고 방식을 제공함으로써
    객체 지향 프로그래밍(OOP)의 부족한 부분을 보완

  • 관심사(기능)의 분리와 핵심 관심사에서 횡단 관심사를 분리하여
    분리한 부가 기능을 Aspect라는 모듈 형태로 만들어 설계/개발 하는 방법
    ➜ 객체 지향적 가치를 높일 수 있게 함

  • 여러 유형과 객체 간에 발생하는 문제의 모듈화를 가능하게 함

  • AOP의 모듈화의 핵심 단위 ➜ 관점 (Aspect) (기능)
    ( OOP의 모듈화의 핵심 단위 ➜ 클래스 (class) )

👉 위 사진을 보면,
각 핵심 관심사(핵심 기능)에 공통적으로 들어가는 기능인 횡단 관심사(부가 기능)을 분리하여 공통적으로 넣어주고 있음 !

💡 Spring DI 가 의존성(new) 에 대한 주입이라면
Spring AOP 는 로직(code) 주입이라고 볼 수 있음 !!

✔️ Aspect

  • 여러 객체에 공통으로 적용되는 기능 ( 횡단 관심사 )
  • Aspect = 어드바이스(Advice) + 포인트컷(PointCut)
    ( 부가 기능을 정의한 코드인 어드바이스(Advice)와
    어드바이스를 어디에 적용할지 결정하는 포인트컷(PointCut)을 합친 개념 )

📌 AOP 관련 용어는 아래 포스팅을 참고해주세요.


✔ Spring AOP의 특징

1. Spring은 프록시 기반 AOP를 지원

  • Spring은 핵심 기능(Target) 객체에 대한 프록시를 만들어 제공

  • 핵심 기능(Target)을 감싸는 프록시(Proxy)는 런타임 시에 생성됨

    프록시 ( Proxy )
    ➜ 어드바이스(Advice)를 타겟(Target) 객체에 적용하면서 생성되는 객체
    ( 부가기능을 핵심기능에 적용하면서 생성되는 객체 )

2. 프록시(Proxy)가 호출을 가로챔(Intercept)

  • 프록시가 핵심 기능(Target) 객체에 대한 호출을 가로채어 해당 조인포인트에 붙은 어드바이스에 따라 수행함

    Ex.

    • 전처리 어드바이스(@Before)의 경우,
      프록시는 타겟 객체에 대한 호출을 가로챈 다음 어드바이스의 부가 기능 로직을 수행하고 난 후에 타겟의 핵심기능 로직을 호출
      ⠀⠀
    • 후처리 어드바이스(@After)의 경우,
      타겟의 핵심 기능 로직 메서드를 호출한 후에 부가 기능(어드바이스)을 수행

3. Spring AOP는 메서드 조인 포인트만 지원

  • Spring은 동적 프록시를 기반으로 AOP를 구현하므로 메서드 조인 포인트만 지원

  • 핵심 기능(Target)의 메서드가 호출되는 런타임 시점에만 부가기능(Advice)을 적용할 수 있다.

  • 반면에 AspectJ 같은 고급 AOP 프레임워크를 사용하면 다양한 작업에 부가 기능 적용 가능
    Ex. 객체의 생성, 필드값의 조회/조작, static 메서드 호출 및 초기화 등에 적용 가능


✏️ AOP 프록시 (proxy)

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

    Ex. 같은 인터페이스를 구현하고 있는 실제 요청 처리 객체와 프록시 객체를 만들고, 프록시 객체가 대신하여 실제 요청 처리를 가짐

  • 스프링에서 생성하는 AOP 프록시는 JDK 동적 프록시 or CGLIB 프록시

✔️ 프록시 (Proxy)

  • '대리' 라는 의미
  • 다른 무언가와 이어지는 인터페이스 역할을 하는 클래스
  • 타겟을 감싸서 요청을 대신 받아주는 랩핑 클래스
    ( Spring에서는 Proxy를 이용해 OOP의 5대 원칙 중 하나인 OCP 적용 )
  • 프록시 객체 = 핵심 기능 외의 공통 기능(부가 기능)을 담은 객체
    ( 어드바이스를 타겟 객체에 적용하면서 생성되는 객체 )
    원래 객체를 감싸서 client의 요청을 대신 처리함

✔ IoC 컨테이너와 AOP Proxy의 관계

Spring AOP는 Proxy의 메커니즘을 기반으로 AOP Proxy를 제공하고 있음 !

위 그림처럼 Spring AOP는 사용자의 특정 호출 시점에 IoC 컨테이너에 의해 AOP를 할 수 있는 Proxy Bean을 생성해줌

동적으로 생성된 Proxy Bean은 핵심 기능(Target)의 메소드가 호출되는 시점에,
부가 기능(Aspect)을 추가할 메소드를 자체적으로 판단하고 가로채어 주입함

➜ 호출 시점에 동적으로 위빙을 하는 런타임 위빙(Runtime Weaving) 방식을 기반으로 함

Spring에선 런타임 위빙을 할 수 있도록 상황에 따라 JDK Dynamic Proxy 방식CGLIB 방식을 통해 Proxy Bean을 생성을 해줌

✔ 두 AOP Proxy는 어떤 상황에서 생성될까?


Spring은 AOP Proxy를 생성하는 과정에서 자체 검증 로직을 통해 타깃의 인터페이스 유무를 판단함

이 때 인터페이스의 유무에 따라,

핵심 기능(Target)이 하나 이상의 인터페이스를 구현하고 있는 클래스라면 ➜ JDK Dynamic Proxy 방식으로,
( But, 기본적으로 Spring은 인터페이스를 구현하는 것을 추천 )

인터페이스를 구현하지 않은 클래스라면 ➜ CGLIB의 방식으로 AOP 프록시를 생성

[참고] https://gmoon92.github.io/spring/aop/2019/04/20/jdk-dynamic-proxy-and-cglib.html


✔ Spring AOP의 구현 방식

1. XML 기반의 POJO 클래스를 이용한 AOP 구현

  • 부가기능을 제공하는 Advice 클래스를 작성

  • XML 설정 파일에 <aop:config>를 이용해서 Aspect를 설정
    ( ➜ 어드바이스와 포인트컷을 설정 )

2. @Aspect 애너테이션을 이용한 AOP 구현

  • @Aspect 애너테이션을 이용하여 부가기능을 제공하는 Aspect 클래스를 작성
    ( 이 때, Aspect 클래스는 어드바이스를 구현하는 메서드와 포인트컷을 포함 )

  • XML 설정 파일에 <aop:aspectj-autoproxy />를 설정

✔️ POJO (Plain Old Java Object)

➜ Java로 생성하는 순수한 객체

✔️ POJO 프로그래밍
➜ POJO를 이용해서 프로그래밍 코드를 작성하는 것

But, 단순히 순수 자바 객체만을 사용한다는 말이 아니라,
(1) 객체지향의 원리에 충실하며 / (2) 다른 환경과 기술에 종속되지 않고 / (3) 다른 기술과 규약에 얽매이지 않은 객체를 사용하여 코드를 작성한다는 말

Spring Framework 사용 전에는 원하는 특정 기술이 있다면 그것을 직접적으로 사용하는 객체를 만들어 사용했었는데,
프로젝트가 커지면서 유지/보수/확장이 어려워지고 Java 언어는 사용하지만 객체지향 설계의 본질을 잃어버리는 문제점이 생김
👉 POJO 개념 등장

📌 POJO ( Plain Old Java Object ) 관련 포스팅


❗ 💬 정리 !!

OOP의 단점을 보완하여 더 객체지향적이고,
반복적인 작업(부가 기능)을 통일해 한번에 하여 효율성을 높이기 위해
관점 지향 프로그래밍 즉, AOP (Aspect Oriented Programming) 기법을 사용한다.

이 AOP는 프로젝트 내의 여러 객체에 공통으로 적용되는 Aspect(부가 기능+넣을 위치)들만 기능별로 따로 묶어, 프록시 객체를 만들어서 한번에 처리하는 기법이다.

이 때, 따로 묶은 Advice들은 그 기능을 어디에(어느 핵심 기능(Target)에) 적용할 지 써줘야하는데

이는 포인트컷(Pointcut)을 활용하여 부가 기능(Advice)을 어느 위치에 넣을 건지 정해줄 수 있고,

어드바이스(Advice)를 활용하여 어느 시점에 넣을 건지 정해줄 수 있다.

여기서, AOP가 적용될 수 있는 모든 지점을 조인포인트(JoinPoint)라고 하고,
그 조인포인트들 중 구체적으로 여기 하겠다! 이게 포인트컷(Pointcut)이다.

즉, 포인트컷을 활용할 수 있는 모든 지점을 조인포인트라고 할 수 있다.

[참고] https://pangtrue.tistory.com/m/80


📌 다음 포스팅은 Spring AOP 용어 정리에 대한 내용입니다.

👉 Spring AOP(Aspect Oriented Programming) 용어 정리 !

0개의 댓글