본문 바로가기
spring

[Spring] AOP(Aspect-Oriented Programming)

by goblin- 2024. 11. 29.

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.ProxyInvocationHandler를 사용.

적용 대상:

인터페이스를 구현한 클래스.

장점:

표준 자바 라이브러리를 사용하여 외부 라이브러리가 필요 없음.

단점:

인터페이스가 없는 클래스에는 적용할 수 없음.

 

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를 효과적으로 활용하려면 핵심 개념과 동작 방식을 이해하고, 프로젝트의 요구 사항에 맞게 적절히 적용하는 것이 중요합니다.