Programming/Spring

[스프링] 관점 지향 프로그래밍 (AOP)

bu119 2023. 6. 29. 17:40
728x90
반응형

AOP의 등장 배경

객체 지향 프로그래밍 (OPP, Object-oriented Programming)

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

Spring MVC에서는 @Controller, @Service, @Repository와 같이 관심사별로 계층을 나눠 객체를 관리하게 된다. 이 관심사의 분리는 모듈화의 핵심이 된다.

 

객체 지향 프로그래밍의 한계 점

  • 특정 관심사 업무 코드에 트랜잭션, 로깅, 보안 등은 필수적인 부가기능이기 때문에 업무 기능과는 상관 없지만 각 클래스에 중복 코드가 존재하게 된다.
  • 관심사 관점에서는 이런 코드들을 횡단관심사(부가기능)이라고 한다.
  • 반대로 업무 관련 코드는 핵심 관심사/기능이라고 한다.
  • 비즈니스 클래스에는 횡단 관심사와 핵심 관심사가 공존하게 된다.

 

OOP만으로는 횡단 관심사 코드를 핵심 기능과 깔끔하게 분리하기 어려웠고, 이런 관심사 분리적 한계를 해결하기 위해 AOP가 등장했다. AOP는 기존과 다른 프로그램 구조 사고방식을 제공함으로써 OOP의 부족한 부분을 보완한다.

OOP 모듈화의 핵심 단위는 클래스이고, AOP 모듈화의 핵심 단위는 관점이라는 차이점이 있다.

 

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

관점(Aspect)에 따라 핵심 기능과 부가 기능을 분리하고, 그렇게 분리한 부가기능의 적용처를 선택하는 기능을 만드는 방식이다.

AOP는 OOP를 대신하는 새로운 개념이 아니라, 기존 OOP를 더욱 보완, 확장하여 OOP를 OOP답게 사용할 수 있도록 도와주는 개념이다. 기능별로 class를 분리했음에도 불구하고 생기는 중복코드의 단점을 해결하고자 나왔다.

 

AOP의 핵심 기능과 부가 기능

  • 핵심 기능 (Core Concerns) - 핵심관심
    • 각 서비스의 핵심 비즈니스 로직
    • 객체가 제공하는 고유의 기능(업무 로직 등을 포함)
    • ex) 계좌이체, 입출금, 이자계산
  • 부가 기능 (Cross-cuttig Concerns) - 횡단 관심
    • 핵심 기능을 보조하기 위해 제공되는 기능이며, 단독으로 사용되지 않고 핵심 기능과 함께 사용된다.
    • ex) 로깅(로그 추적 로직), 보안, 트랜잭션

 

AOP가 필요한 이유

소프트웨어 개발에서 변경 지점은 하나가 될 수 있도록 모듈화하는 게 중요한데, 부가 기능처럼 특정 로직을 애플리케이션 전반에 적용하는 문제는 일반적인 객체지향 프로그래밍 방식으로는 해결이 어렵기 때문에 핵심 기능과 부가 기능을 분리하는 AOP 방식이 필요하다.

 

AOP의 장점

  • 소스 코드에서 여러 번 반복해서 쓰는 코드(= 흩어진 관심사, Concern)를 Aspect로 모듈화하여 핵심 로직에서 분리 및 재사용할 수 있게 한다.
  • 개발자가 핵심 로직에 집중할 수 있게 한다.
  • 주로 부가 기능을 모듈화한다.

 

AOP 용어 및 개념 정리

애스펙트 (Aspect)

  • 여러 객체에 공통으로 적용되는 기능이다. (공통 기능)
  • 일정한 패턴을 가지는 클래스에 Advice를 적용하도록 지원할 수 있는 것을 Aspect라고 한다.
  • Advice와 Pointcut을 합쳐서 하나의 Aspect라고 한다.
    • 어드바이스(Advice) + 포인트 컷(PointCut)을 모듈화 하여 애플리케이션에 포함되는 횡단 기능(Cross-cutting Concerns) 이다.
  • 여러 개의 어드바이스와 포인트컷이 함께 존재한다.
  • ex) 트랜잭션 기능/로그 기능/보안 기능/인증 기능 등

 

조인 포인트 (Join point)

  • 클래스 초기화, 객체 인스턴스화, 메서드 호출, 필드 접근, 예외 발생과 같은 애플리케이션 실행 흐름에서의 특정 포인트를 의미한다.
  • 추상적인 개념으로 AOP를 적용할 수 있는 모든 지점이다.
  • 스프링 AOP는 프록시 방식을 사용하여 조인포인트가 항상 메서드의 실행 지점으로 제한된다.

 

어드바이스 (Advice)

  • 실질적인 부가 기능 로직을 정의하는 곳이다.
  • 조인 포인트에서 수행되는 코드를 의미한다.
  • Aspect를 언제 핵심 코드에 적용할지 정의한다.
  • 시스템 전체 Aspect에 API 호출 제공한다.

 

포인트컷 (PointCut)

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

 

위빙 (Weaving)

  • 포인트컷으로 결정한 타겟의 조인 포인트에 어드바이스를 적용하는 것으로 Advice를 핵심 코드에 적용하는 것이다.
  • 핵심 기능 코드에 영향을 주지 않고 부가 기능을 추가할 수 있다.
  • AOP 적용을 위해 Aspect 객체에 연결한 상태를 뜻한다.
    • 컴파일 타임(AspectJ compooiler)
    • 로드 타임
    • 런타임
    • 스프링 AOP는 런타임, 프록시 방식

 

AOP 프록시 (Proxy)

  • AOP 기능을 구현하기 위해 만든 프록시 객체이다.
  • 스프링에서 AOP 프록시는 JDK 동적 프록시 또는 CGLIB 프록시를 뜻한다.
  • 스프링 AOP의 기본값은 CGLIB 프록시이다.

 

타겟 (Target)

  • 핵심 기능을 담고 있는 모듈로 타겟은 부가기능을 부여할 대상이 된다.
  • Advice를 받는 객체이고 포인트컷으로 결정된다.

 

어드바이저 (Advisor)

  • 하나의 어드바이스와 하나의 포인트컷으로 구성된다.
  • 스프링 AOP에서만 사용되는 특별한 용어이다.

 

어드바이스 (Advice)

  • Aspect를 언제 핵심 코드에 적용할지를 정의
  • 특정 조인 포인트에서 애스펙트에 의해 취해지는 조치

 

스프링 AOP의 특징

  1. 스프링에서 AOP 구현은 접근 제어 및 부가기능을 추가하기 위해서 Proxy를 이용한다. 이 때문에 다른 AOP의 기능과 비교해서 매우 제한적인 부분만을 지원한다.
  2. 스프링 내에 프록시 빈에서만 AOP를 적용 가능하다. 설정 구조 상 다른 XML기반의 AOP에 비해 복잡한 편이다.
  3. 모든 AOP 기능을 제공하는 것이 아닌 스프링 IoC(제어의 역전)와 연동하여 엔터프라이즈 애플리케이션에서 가장 흔한 문제에 대한 해결책을 지원하는 것이 목적이다.

 

AOP가 사용되는 경우

  1. 간단한 메소드 성능 검사 개발 도중 특히 DB에 다량의 데이터를 넣고 빼는 등의 배치 작업에 대하여 시간을 측정해보고 쿼리를 개선하는 작업은 매우 의미가 있다. 이 경우 매번 해당 메소드 처음과 끝에 System.currentTimeMills();를 사용하거나, 스프링이 제공하는 StopWatch코드를 사용하기는 매우 번거롭다. 이런 경우 해당 작업을 하는 코드를 밖에서 설정하고 해당 부분을 사용하는 편이 편리하다.
  2. 트랜잭션 처리 트랜잭션의 경우 비지니스 로직의 전후에 설정된다. 하지만 매번 사용하는 트랜잭션 (try~catch부분)의 코드는 번거롭고, 소스를 더욱 복잡하게 보여준다.
  3. 예외 반환 스프링에는 DataAccessException이라는 매우 잘 정의되어 있는 예외 계층 구조가 있다. 예전 하이버네이트 예외들은 몇 개 없었고 그나마도 Uncatched Exception이 아니였다. 이렇게 구조가 별로 안 좋은 예외들이 발생했을 때, 그걸 잡아서 잘 정의되어 있는 예외 계층 구조로 변환해서 다시 던지는 애스팩트는 제 3의 프레임워크를 사용할 때, 본인의 프레임워크나 애플리케이션에서 별도의 예외 계층 구조로 변환하고 싶을 때 유용하다.
  4. 아키텍처 검증
  5. 기타
  • 하이버네티스와 JDBC를 같이 사용할 경우, DB 동기화 문제 해결
  • 멀티쓰레드 Safety 관련하여 작업해야 하는 경우, 메소드들에 일괄적으로 락을 설정하는 애스팩트
  • 데드락 등으로 인한 PessimisticLockingFailureException등의 예외를 만났을 때 재시도하는 애스팩트
  • 로깅, 인증, 권한 등

참고자료

https://ittrue.tistory.com/232

https://velog.io/@backtony/Spring-AOP-%EC%B4%9D%EC%A0%95%EB%A6%AC

https://greendreamtrre.tistory.com/601

https://hoi5088.medium.com/%EA%B4%80%EC%A0%90%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-aop-557d1a2250c4

https://velog.io/@gillog/AOP%EA%B4%80%EC%A0%90-%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D

https://velog.io/@artwoojin/%EA%B4%80%EC%A0%90%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8DAOP-vs-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8DOOP

728x90
반응형