1. AOP(관점 지향 프로그래밍)란 무엇인가?
1.1 정의
**AOP(Aspect-Oriented Programming)**는 소프트웨어 개발 패러다임 중 하나로, 프로그램의 핵심 비즈니스 로직과는 별도로 여러 모듈에 공통적으로 적용되는 **횡단 관심사(Cross-Cutting Concerns)**를 분리하여 모듈화 하는 방법입니다.
• 횡단 관심사: 애플리케이션의 여러 부분에 걸쳐 공통적으로 사용되는 기능으로, 예를 들면 로깅(logging), 보안(security), 트랜잭션 관리(transaction management) 등이 있습니다.
• 핵심 관심사: 애플리케이션의 주요 비즈니스 로직이나 기능을 담당하는 부분입니다.
1.2 필요성
• 코드 모듈화 향상: 횡단 관심사를 별도의 모듈로 분리함으로써 코드의 응집도를 높이고 결합도를 낮춥니다.
• 유지보수성 개선: 공통 기능을 한 곳에서 관리하므로 변경 사항이 있을 때 수정해야 할 코드의 범위가 줄어듭니다.
• 코드 중복 감소: 여러 모듈에서 반복되는 코드를 제거하여 코드의 간결성과 가독성을 높입니다.
• 비즈니스 로직 집중: 핵심 로직에만 집중할 수 있어 개발 생산성이 향상됩니다.
2. OOP와 AOP의 비교
2.1 OOP(Object-Oriented Programming, 객체 지향 프로그래밍)
• 주요 개념: 클래스, 객체, 상속, 캡슐화, 다형성 등을 사용하여 시스템을 설계합니다.
• 관심사의 분리: 데이터와 그 데이터를 처리하는 메서드를 하나의 객체로 캡슐화합니다.
• 한계점: 횡단 관심사를 효과적으로 분리하기 어렵습니다. 예를 들어, 로깅이나 보안 처리를 각 클래스마다 구현해야 하며 이는 코드 중복과 유지보수의 어려움을 초래합니다.
2.2 AOP의 접근 방식
• 횡단 관심사의 분리: AOP는 OOP로는 분리하기 어려운 횡단 관심사를 별도의 모듈(Aspect)로 분리합니다.
• 관점(Aspect) 도입: 프로그램 전반에 걸쳐 공통적으로 적용되는 기능을 Aspect로 정의하여 관리합니다.
• 코드 침투 최소화: 핵심 비즈니스 로직 코드에 부가 기능 코드가 섞이지 않도록 하여 코드의 명확성을 유지합니다.
3. AOP의 핵심 개념
3.1 Aspect (애스펙트)
• 정의: 횡단 관심사를 모듈화한 것입니다. 즉, 여러 부분에 공통적으로 적용되어야 하는 기능을 하나의 모듈로 캡슐화한 것입니다.
• 역할:
• 횡단 관심사의 캡슐화
• 유지보수성 향상
• 예시:
• 로깅 Aspect: 메서드 실행 전후로 로그를 남기는 기능.
• 트랜잭션 Aspect: 데이터베이스 작업에 대한 트랜잭션 처리를 관리.
3.2 Join Point (조인 포인트)
• 정의: 프로그램 실행 중에 Aspect가 적용될 수 있는 지점을 의미합니다.
• 특징:
• 잠재적 적용 지점으로, 메서드 호출, 예외 발생, 필드 접근 등이 포함됩니다.
• 스프링 AOP에서의 Join Point:
• 주로 메서드 실행 지점만을 Join Point로 인정합니다.
3.3 Pointcut (포인트컷)
• 정의: Join Point의 부분집합으로, Aspect를 적용할 실제 지점을 지정하는 표현식입니다.
• 역할:
• 특정 조건을 사용하여 어떤 Join Point에 Aspect를 적용할지 지정합니다.
• 필터링 기능을 통해 필요한 지점만 선택하여 Advice를 적용합니다.
• 예시:
• execution(* com.example.service.*.*(..)): 특정 패키지의 모든 메서드 선택.
• @annotation(org.springframework.transaction.annotation.Transactional): 특정 애노테이션이 붙은 메서드 선택.
3.4 Advice (어드바이스)
• 정의: Aspect가 Join Point에서 수행할 구체적인 동작을 정의한 것입니다.
• 종류:
1. Before Advice: 메서드 실행 전에 실행.
2. After Returning Advice: 메서드가 정상적으로 실행된 후에 실행.
3. After Throwing Advice: 메서드 실행 중 예외가 발생했을 때 실행.
4. After (Finally) Advice: 메서드 실행 여부와 상관없이 항상 실행.
5. Around Advice: 메서드 실행 전후에 모두 실행되며, 실행 자체를 제어할 수 있음.
• 예시:
• 메서드 실행 전후로 실행 시간을 측정하는 기능.
3.5 Weaving (위빙)
• 정의: 정의된 Aspect를 실제 타겟 객체에 적용하여 동작하도록 만드는 과정입니다.
• 종류:
1. 컴파일 타임 위빙: 소스 코드를 컴파일할 때 Aspect를 적용.
2. 로드 타임 위빙: 클래스 로더가 클래스를 로드하는 시점에 Aspect를 적용.
3. 런타임 위빙: 애플리케이션 실행 중에 프록시 패턴을 사용하여 Aspect를 적용.
• 역할:
• Aspect를 비즈니스 로직에 결합하여 횡단 관심사가 실행되도록 합니다.
4. Weaving의 종류와 동작 방식
4.1 컴파일 타임 위빙
• 메커니즘: AspectJ 컴파일러(ajc)를 사용하여 소스 코드를 컴파일하면서 Aspect를 적용.
• 특징:
• 런타임 오버헤드가 없음.
• 빌드 프로세스에 AspectJ 컴파일러를 포함시켜야 함.
• 사용 사례:
• 성능이 중요한 애플리케이션에서 사용.
4.2 로드 타임 위빙
• 메커니즘: 클래스 로더를 통해 바이트코드를 조작하여 Aspect를 적용.
• 특징:
• JVM 옵션이나 에이전트를 설정해야 함.
• 동적으로 Aspect를 추가하거나 제거할 수 있음.
• 사용 사례:
• 이미 컴파일된 클래스 파일에 Aspect를 적용해야 할 때.
4.3 런타임 위빙
• 메커니즘: 프록시 패턴을 사용하여 메서드 호출을 가로채고 Aspect를 적용.
• 특징:
• 스프링 AOP에서 주로 사용하는 방식.
• JDK 동적 프록시 또는 CGLIB를 사용.
• 사용 사례:
• 스프링 프레임워크에서 AOP를 적용할 때.
위빙 방식 | 시점 | 메커니즘 | 분류 | 특징 |
컴파일 타임 위빙 | 컴파일 시점 | 컴파일러(AspectJ ajc) | 컴파일 방식 | 런타임 오버헤드 없음 빌드 설정 필요 |
로드 타임 위빙 | 클래스 로딩 시점 | 클래스 로더바이트코드 조작 | 클래스 로드 방식 | 동적 적용 가능JVM 설정 필요 |
런타임 위빙 | 런타임 시점 | 프록시 객체(JDK 동적 프록시, CGLIB) | 프록시 방식 | 스프링 AOP 사용제한 사항 존재 |
주로 런타임 위빙 사용
5. 프록시 생성 방식: JDK Dynamic Proxy와 CGLIB
5.1 JDK Dynamic Proxy
• 동작 방식:
• 인터페이스를 기반으로 프록시 객체를 생성.
• java.lang.reflect.Proxy와 InvocationHandler를 사용.
• 적용 대상:
• 인터페이스를 구현한 클래스.
• 장점:
• 표준 자바 라이브러리를 사용하여 외부 라이브러리가 필요 없음.
• 단점:
• 인터페이스가 없는 클래스에는 적용할 수 없음.
5.2 CGLIB
• 동작 방식:
• 구체 클래스를 상속받아 프록시 객체를 생성.
• 바이트코드 조작을 통해 메서드를 오버라이드.
• 적용 대상:
• 인터페이스가 없는 구체 클래스.
• 장점:
• 인터페이스 없이도 프록시 생성 가능.
• 단점:
• final 클래스나 final 메서드에는 적용할 수 없음.
• 외부 라이브러리(CGLIB)가 필요함.
6. 스프링에서의 AOP 구현
6.1 스프링 AOP의 특징
• 런타임 위빙 사용: 프록시 패턴을 사용하여 Aspect를 적용.
• 자동 프록시 생성: @EnableAspectJAutoProxy 애노테이션을 통해 AOP를 활성화.
• 적용 대상 제한:
• final 클래스나 메서드에는 Aspect를 적용할 수 없음.
• 메서드 내부 호출에는 Aspect가 적용되지 않음.
6.2 스프링에서의 프록시 선택 기준
• 인터페이스가 있는 경우: JDK Dynamic Proxy를 사용.
• 인터페이스가 없는 경우: CGLIB를 사용.
• CGLIB 강제 사용:
• @EnableAspectJAutoProxy(proxyTargetClass = true)로 설정.
7. AOP 실제 적용 예시
Spring Boot @AspectJ 애노테이션 기반 AOP 방식
https://sung-98.tistory.com/193
8. 결론
**AOP(Aspect-Oriented Programming)**는 횡단 관심사를 모듈화하여 코드의 모듈화와 유지보수성을 향상시키는 강력한 프로그래밍 패러다임입니다. 스프링 프레임워크는 AOP를 지원하여 개발자가 핵심 비즈니스 로직에 집중할 수 있도록 돕습니다.
AOP를 효과적으로 활용하려면 핵심 개념과 동작 방식을 이해하고, 프로젝트의 요구 사항에 맞게 적절히 적용하는 것이 중요합니다.
'spring' 카테고리의 다른 글
[Spring] 프록시(proxy) (0) | 2024.11.30 |
---|---|
[Spring] AOP 실제 적용 예시 (1) | 2024.11.29 |
[Spring] 물리 트랜잭션, 논리 트랜잭션 (0) | 2024.11.28 |
[Spring] @Transaction (1) | 2024.11.28 |
[Spring] Spring의 트랜잭션 동기화(Transaction Synchronization) (0) | 2024.11.28 |