❑ 관점 지향 프로그래밍(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 기본 용어 정리
➤ 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
➤ Spring AOP와 AspectJ
▶️ Spring AOP
- 목적 : Spring IoC를 통한 간단한 AOP 구현 -> 완전한 AOP를 의도한 것이 아님
- Spring Container에 의해 관리되는 bean에만 적용 가능
▶️ AspectJ
- 목적 : 완전한 AOP를 제공하는것
- Spring보다 강력하지만 복잡하다
- 모든 객체에 적용이 가능하다
참고) Bealdung 자료 번역 글
https://logical-code.tistory.com/118
읽어주셔서 감사합니다.
오개념에 대한 지적은 언제나 환영입니다.
'TIL(Today I Learned)' 카테고리의 다른 글
6/23 (목) [Spring MVC] API 계층 - 1️⃣ Spring MVC Architecture & Controller (0) | 2022.06.26 |
---|---|
6/21 (화) Spring Framework - AOP 2️⃣ (0) | 2022.06.21 |
6/18 (토) Spring Framework - DI(Dependency Injection) 2️⃣ 빈 스코프(Bean Scope) (0) | 2022.06.19 |
6/17 (금) Spring Framework - DI(Dependency Injection) 1️⃣ Spring Container와 Bean (0) | 2022.06.18 |
6/15 (수) Spring Framework 모듈, Spring Boot (0) | 2022.06.17 |