❑ 관점 지향 프로그래밍(Aspect-Oriented Programming, AOP)

 

 

AOP(관점 지향 프로그래밍)가 OOP(객체 지향 프로그래밍)을 대체? ❎

횡단 관심사(부가 관심사)를 깔끔하게 처리하기 위해 OOP의 부족한 부분을 보조하는 목적으로 생겨난 것이다.

 

부가 관심사

 

 

 

❑ AOP가 필요한 이유

 

 

➤ AOP 기본 개념

 

핵심 기능(Core Concerns) : 업무 로직을 포함하는 기능

부가 기능(CROSS-CUTTING CONCERNS) : 핵심 기능을 도와주는 부가적인 기능 (로깅, 보안, 트랜잭션 등)

Aspect : 부가 기능을 정의한 코드인 Advice와 Advice를 어디에 적용할지 결정하는 포인트컷(PointCut)을 합친 개념 (Advice + PointCut -> Aspect)

 

 

 

➤ 객체 지향 프로그래밍(OOP)

 

  • 공통된 목적을 띈 데이터와 동작을 묶어 하나의 객체로 정의
  • 객체를 적극적으로 활용하여 기능을 재사용할 수 있는 것이 큰 장점
  • 객체를 잘 활용하기 위해선 관심사 분리(Separation of Concerns, SoC)의 디자인 원칙을 준수해야함

 

 

 

➤ OOP의 한계

 

  • 비즈니스 코드에 트랜잭션, 보안, 로깅 등의 코드가 존재하게 된다.
  • 위의 기능은 업무와는 관련없지만 필수적인 부가 기능이라서 빠질 수 없다.
  • 부가 기능은 불특정 다수 클래스에 존재하게 된다.
  • 비즈니스 클래스에 횡단 관심사와 핵심 관심사가 공존하게 된다.
  • 메소드 복잡도 증가 -> 비즈니스 핵심 로직 코드 파악하기 어려움
  • 부가 기능의 불특정 다수 메소드 반복적으로 구현 -> 횡단 관심사의 모듈화가 어려움

 

관심사의 분리는 모듈화의 핵심이다.

OOP만으로는 횡단 관심사 코드를 깔끔하게 분리하고 비즈니스 코드에 적용하기 어려웠다.

이러한 문제를 해결하기 위해 AOP가 등장했다.

 

 

 

➤ AOP의 핵심 기능과 부가 기능

 

 

▶️ 핵심 기능(Core Concerns)

객체가 제공하는 고유의 기능(업무 로직 등)

 

 

▶️ 부가 기능(CROSS-CUTTING CONCERNS)

핵심 기능을 보조하기 위해 제공되는 기능

로그 추적 로직, 보안, 트랜잭션 기능 등

단독으로 사용되지 않고 핵심 기능과 함께 사용됨

 

 ⬇️ 핵심 기능과 부가 기능 모델

핵심 기능과 부가 기능

 

특징

  • 핵심 기능인 XX로직과 부가 기능인 로그 추적 로직이 하나의 객체에 들어간다.
  • 부가 기능이 필요한 경우엔 위와 같이 합쳐져서 하나의 로직을 완성하게 된다.
  • 서비스를 실행하면 핵심 기능과 부가 기능이 함께 실행된다.

 

 

 

➤ 공통으로 사용하는 부가 기능

 

부가 기능은 보통 여러 클래스에서 함께 사용한다.

이러한 부가 기능은 횡단 관심사가 된다.

부가 기능을 여러 곳에 적용하려면 중복 코드가 생기게 되고 그렇게 되면 수정할 때 각각의 클래스를 찾아가면서 수정해야 한다.

 

 

➤ AOP가 필요한 이유

 

소프트웨어에서 변경지점은 하나가 될 수 있도록 잘 모듈화가 되어야 한다.

부가 기능을 애플리케이션 전반에 적용하는 문제는 OOP 방식으로는 해결이 어렵기 때문에 AOP가 필요하다.

 

 

 

 

❑ AOP 기본 용어 정리

 

 

 

AOP 기본 용어

 

 

 

➤ Aspect(애스팩트)

 

여러 객체에 공통으로 적용되는 기능

Advice + Pointcut 을 모듈화하여 애플리케이션에 포함되는 횡단 기능

여러 어드바이스와 포인트컷이 함께 존재함

 

 

 

➤ Join Point (조인 포인트)

 

  • AOP를 적용할 수 있는 모든 지점을 나타내는 추상적인 개념이다.
  • 클래스 초기화, 객체 인스턴스화, 메서드 호출, 필드 접근, 예외 발생과 같은 애플리케이션 실행 흐름에서의 특정 포인트를 의미한다.
  • 애플리케이션에 새로운 동작을 추가하기 위해 조인포인트에 관심 코드(aspect code)를 추가할 수 있다.
  • 횡단 관심은 조인포인트 전/후에 AOP에 의해 자동으로 추가된다.
  • 스프링 AOP는 프록시 방식을 사용하므로 조인 포인트는 항상 메서드 실행 지점으로 제한된다.

 

 

 

➤ Advice(어드바이스)

 

  • join point에서 수행되는 코드를 의미한다.
  • Aspect를 언제 핵심 코드에 적용할 지를 정의한다.
  • 시스템 전체 aspect에 API 호출을 제공한다.
  • 부가 기능에 해당된다.

 

 

 

➤ Pointcut(포인트컷)

 

  • 조인포인트 중에서 어드바이스가 적용될 위치를 선별하는 기능이다.
  • AspectJ 표현식을 사용해서 지정한다.
  • 프록시를 사용하는 스프링 AOP는 메서드 실행 지점만 포인트컷으로 선별 가능하다.

 

 

 

➤ Weaving(위빙)

 

  • pointcut으로 결정한 target의 joinpoint에 advice를 적용하는 것이다. -> advice를 핵심코드에 적용하는 것
  • 핵심 기능 코드에 영향을 주지 않고 부가 기능을 추가할 수 있다.
  • AOP 적용을 위해 aspect 객체에 연결한 상태이다.

 

 

 

➤ AOP 프록시(proxy)

 

  • AOP 기능을 구현하기 위해 만든 프록시 객체이다.
  • 스프링에서 AOP 프록시는 JDK 동적 프록시나 CGLIB 프록시 중 하나이다.

※ 프록시에 대한 자세한 내용은 글 하단부에 작성했다.

 

 

➤ Target(타겟)

 

  • 핵심 기능을 담고 있는 모듈
  • 부가 기능을 적용할 대상
  • Advice 받는 객체, 포인트컷으로 결정

 

 

➤ Advisor(어드바이저)

 

하나의 어드바이스와 하나의 포인트 컷으로 구성된다.

 

 

 

 

❑ 추가 학습

 

 

➤ Spring Proxy(프록시)

 

Spring AOP는 프록시 기반이다.

Spring에서 사용하는 프록시는 JDK dynamic 프록시와 CGLIB 프록시로 두가지다.

메서드를 직접 부르지 않고 프록시를 통해서 메서드를 불러온다.

프록시는 대리자 역할을 한다고 볼 수 있다.

 

 

▶️ JDK Dynamic proxy vs. CGLIB proxy

 

※ JDK Dynamic proxy (JDK 동적 프록시)

  • JDK와 함께 사용할 수 있다.
  • Reflaction을 통해 동적으로 프록시 객체 생성
  • 해당 타겟에 의해 구현된 모든 인터페이스가 프록시 된다.
  • 인터페이스를 구현하는 경우 스프링은 자동으로 JDK 동적 프록시를 사용한다.

 

 

※ CGLIB

  • 스프링이 프록시를 만들기 위해 사용하는 third party library 이다.
  • 클래스 상속을 통해 프록시 객체 생성
  • 구현한 인터페이스가 없을 때 사용한다.

 

 

참고) 프록시 공식 레퍼런스

https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch08s06.html

 

8.6 Proxying mechanisms

Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxy for a given target object. (JDK dynamic proxies are preferred whenever you have a choice). If the target object to be proxied implements at least one interface then a JDK dynamic proxy

docs.spring.io

 

 

 

➤ Spring AOP와 AspectJ

 

 

▶️ Spring AOP

  • 목적 : Spring IoC를 통한 간단한 AOP 구현 -> 완전한 AOP를 의도한 것이 아님
  • Spring Container에 의해 관리되는 bean에만 적용 가능

 

 

▶️ AspectJ

  • 목적 : 완전한 AOP를 제공하는것
  • Spring보다 강력하지만 복잡하다
  • 모든 객체에 적용이 가능하다

 

 

참고) Bealdung 자료 번역 글

https://logical-code.tistory.com/118

 

Spring AOP와 AspectJ 비교하기

Thanks to @ㅅㅈㅎ 님 덕분에 3-5 첫번째 문장의 오타를 수정했습니다. 감사합니다! (더 간편합니다다. ⇢ 더 간편합니다.) @김성수 님 덕분에 3-2. Weaving의 오타를 수정했습니다. 감사합니다! (컴파일

logical-code.tistory.com

 

 

 

 

읽어주셔서 감사합니다.

오개념에 대한 지적은 언제나 환영입니다.