4.6 KiB
4.6 KiB
category, tags, title, description, last_updated
| category | tags | title | description | last_updated | |||
|---|---|---|---|---|---|---|---|
| Computer_Science_and_Theory |
|
AOP (Aspect-Oriented Programming) | AOP(Aspect-Oriented Programming)는 로깅, 보안, 트랜잭션 관리와 같은 횡단 관심사(Cross-Cutting Concerns)를 소프트웨어 시스템의 여러 모듈에서 분리하여 관리하는 방법론이자 프로그래밍 기법입니다 [1, 2]. | 2026-05-04 |
AOP (Aspect-Oriented Programming)
📌 Brief Summary
AOP(Aspect-Oriented Programming)는 로깅, 보안, 트랜잭션 관리와 같은 횡단 관심사(Cross-Cutting Concerns)를 소프트웨어 시스템의 여러 모듈에서 분리하여 관리하는 방법론이자 프로그래밍 기법입니다 [1, 2]. 핵심 비즈니스 로직과 인프라 코드를 분리함으로써 소스 코드의 오염을 방지하고 코드의 가독성과 유지보수성을 크게 높여줍니다 [3, 4]. 주로 런타임에 메서드 호출을 가로채어 실행 전, 후, 또는 주변(around)에 원하는 동작을 적용하는 방식으로 작동합니다 [1, 2].
📖 Core Content
- 관심사의 분리 (Separation of Concerns): 소프트웨어는 주요 기능을 담당하는 핵심 관심사(Core Concerns, 비즈니스 로직)와 시스템 전반에 걸쳐 필요한 보조 기능인 횡단 관심사(Crosscutting Concerns)로 나뉩니다 [5]. AOP는 로깅, 데이터 전송, 보안, 성능 모니터링, 캐싱 등 애플리케이션의 여러 계층을 가로지르는 횡단 관심사를 별도의 '애스펙트(Aspect)'로 분리하여 관리합니다 [1, 5].
- Spring Boot에서의 실전 구현: Spring 생태계에서 AOP는 컨트롤러, 서비스, 리포지토리 등 모든 Spring Bean의 메서드를 인터셉트할 수 있는 애플리케이션 및 서비스 계층의 기술로 활용됩니다 [1, 6]. 개발자는
@Aspect를 사용하여@Before,@After,@Around등의 시점(Pointcut)을 정의해 비즈니스 로직의 수정 없이 공통 기능을 주입할 수 있습니다 [1, 6]. - 주요 활용 사례:
- 트랜잭션 동작(Transactional Behavior): 모든 서비스 메서드에
try-catch블록과commit/rollback호출을 반복 작성하는 대신, 어노테이션 마커를 통해 트랜잭션 처리 책임을 AOP에 위임합니다 [7]. - 인가(Authorization): 서비스 메서드를 호출할 수 있는 권한을 마커로 표시하고, AOP 어드바이스(Advice)가 해당 메서드의 실행 허용 여부를 동적으로 결정하게 합니다 [8].
- 원격 호출(Remoting): 분산 시스템 환경에서 대상 식별, 데이터 직렬화, 원격 네트워크 호출 등의 복잡한 처리를 애스펙트가 대신 수행하여, 개발자는 로컬 컴포넌트를 호출하는 것처럼 코드를 작성할 수 있습니다 [9].
- 트랜잭션 동작(Transactional Behavior): 모든 서비스 메서드에
- 코드 품질 및 설계 향상: AOP를 통해 공통 인프라 로직을 캡슐화하면 코드의 산재(Scattering)와 얽힘(Tangling)을 효과적으로 방지할 수 있습니다 [3, 10]. 이는 DRY(Don't Repeat Yourself) 원칙과 단일 책임 원칙(SRP) 위반을 막아주어, 대규모 코드베이스를 깨끗하고 리팩토링하기 쉬운 상태로 유지하도록 돕습니다 [3, 11].
⚖️ Trade-offs & Caveats
- 디버깅 난이도 상승 (마법 같은 동작): AOP는 비즈니스 코드와 인프라 코드를 완벽하게 분리하는 강력한 장점이 있지만, 실행 시점에 동적으로 로직을 삽입하므로 코드의 실제 실행 흐름을 직관적으로 파악하기 어렵게 만듭니다 [4]. 이러한 지나치게 '마법 같은(magical)' 동작 방식은 예기치 않은 오류 발생 시 추적과 디버깅을 매우 까다롭게 만드는 부작용이 있습니다 [4].
- 런타임 성능 오버헤드: Castle.DynamicProxy와 같은 런타임 인터셉터 프레임워크를 사용할 경우, 각 메서드나 클래스에 대한 프록시 래퍼(Proxy wrapper)를 동적으로 생성해야 하므로 추가적인 런타임 비용이 발생합니다 [12]. 로깅과 같이 매우 빈번하게 호출되는 연산에 전면적으로 적용할 경우 애플리케이션 전반의 성능을 저하시킬 수 있습니다 [12].
- 빌드 파이프라인의 복잡성 증가: 성능 오버헤드라는 제약을 피하기 위해 런타임 프록시 대신 컴파일 타임(Compile-time)이나 링크 타임(Link-time) 위빙(Weaving) 방식으로 AOP를 구현할 수 있습니다 [12]. 하지만 이 최적화 방법은 빌드 과정 자체를 훨씬 복잡하게 만드는 반대급부를 수반합니다 [12].
Last updated: 2026-05-03