관점 지향 프로그래밍
프로그램의 핵심 로직과 공통적으로 사용되는 기능(횡단 관심사)을 분리하여 코드를 더 간결하고 유지보수하기 쉽게 만드는 프로그래밍 기법
스프링에서 AOP는 애플리케이션 전반에 걸친 공통 로직을 캡슐화 하는데 사용
주요 개념
1. 횡단 관심사 (Cross-Cutting Concern)
- 여러 클래스나 메서드에서 반복적으로 나타나는 공통 기능
- 예 : 로깅, 트랜잭션 관리, 보안 검사 등
2. 핵심 관심사 (Core Concern)
- 애플리케이션의 주요 비즈니스 로직
3. AOP의 역할
- 횡단 관심사를 핵심 관심사에서 분리하여 모듈화
- 코드 중복을 줄이고 비즈니스 로직에만 집중할 수 있도록 돕는다
AOP에서 사용하는 주요 용어
1. Aspect
- 횡단 관심사를 모듈화한 코드 단위
- 예 : 로깅 기능을 캡슐화한 모듈
2. Join Point
- 애플리케이션 실행 중에 AOP가 삽입될 수 있는 특정 지점
- 예 : 메서드 호출, 객체 생성
3. Advice
- Join Point에서 실행될 동작(로직)
- Advice는 언제 실행될지를 정의함
- 종류 :
- Before Advice : 메서드 실행 전에 실행
- After Returning Advice : 메서드가 정상적으로 실행된 후 실행
- After Throwing Advice : 예외가 발생한 후 실행
- After (Finally) Advice : 메서드 실행 후 항상 실행
- Around Advice : 메서드 실행 전후에 실행
4. Pointcut
- Advice가 적용될 Join Point를 선택하는 표현식
- 예 : 특정 패키지나 클래스 내의 메서드에만 적용
5. Weaving
- Aspect와 애플리케이션 코드를 결합하는 과정
- 실행 시점 :
- 컴파일 타임 : 컴파일 시에 코드에 Aspect를 삽입
- 로드 타임 : 클래스 로딩 시에 Aspect를 삽입
- 런타임 : 실행 중에 프록시 객체를 사용해 Aspect를 적용(스프링 AOP가 사용하는 방식)
특징
1. 프록시 기반 :
- 스프링 AOP는 프록시 패턴을 사용하여 Aspect를 적용
- 프록시는 실제 객체의 대리 역할을 하며, 프록시를 통해 로직이 실행되기 전에 AOP 동작이 추가됨
2. 메서드 수준 지원 :
- 스프링 AOP는 Join Point로 메서드 호출만 지원(필드, 생성자 등은 지원하지 않음)
3. 선언적 방식 :
- 주로 어노테이션과 XML 설정을 통해 Aspect를 정의
구현 방법
1. 의존성 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2. @Aspect 사용
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
// Pointcut: 특정 패키지 내 모든 메서드에 Advice 적용
@Before("execution(* com.example.service.*.*(..))")
public void logBeforeMethod() {
System.out.println("Method is about to execute");
}
}
3. Pointcut 표현식
execution을 사용해 Pointcut을 정의함
표현식 예시 | 설명 |
execution(* com.example.service.*.*(..)) | com.example.service 패키지 내 모든 메서드 |
execution(public * *(..)) | 모든 public 메서드 |
execution(* *.*(..)) | 모든 메서드 |
execution(* com.example..*.*(..)) | com.example 하위 모든 패키지의 모든 메서드 |
Advice 종류별 예제
1. Before Advice
@Before("execution(* com.example.service.*.*(..))")
public void beforeAdvice() {
System.out.println("Before method execution");
}
2. After Returning Advice
@AfterReturning("execution(* com.example.service.*.*(..))")
public void afterReturningAdvice() {
System.out.println("After successful method execution");
}
3. After Throwing Advice
@AfterThrowing("execution(* com.example.service.*.*(..))")
public void afterThrowingAdvice() {
System.out.println("Exception occurred during method execution");
}
4. Around Advice
@Around("execution(* com.example.service.*.*(..))")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Before method execution");
Object result = joinPoint.proceed(); // 실제 메서드 실행
System.out.println("After method execution");
return result;
}
AOP의 실제 활용 사례
1. 로깅 :
- 모든 메서드 호출에 대해 실행 정보를 기록
2. 트랜잭션 관리 :
- 특정 비즈니스 로직이 시작되면 트랜잭션을 열고, 끝날 때 닫음
3. 보안 검사 :
- 메서드 실행 전에 사용자 권한을 검사
4. 성능 모니터링 :
- 메서드 실행 시간을 측정
장점
1. 코드 중복 제거 :
- 횡단 관심사를 분리하여 중복된 코드를 제거
2. 유지보수성 향상 :
- 핵심 로직과 부가 로직이 분리되어 코드가 더 명확해짐
3. 재사용 가능 :
- 공통 로직을 여러 클래스에서 재사용 가능
단점
1. 복잡성 증가 :
- AOP 설정과 Pointcut 표현식이 복잡해질 수 있음
2. 디버깅 어려움 :
- 프록시 기반 동작으로 인해 실행 흐름 추적이 어려울 수 있음
3. 오용 위험 :
- 적절히 사용하지 않으면 코드 가독성과 성능이 저하될 수 있음
요약
- AOP는 횡단 관심사(로깅, 트랜잭션 등)를 핵심 비즈니스 로직과 분리하여 모듈화하는 기법
- 스프링에서는 주로 프록시 기반으로 AOP를 구현
- 주요 개념: Aspect, Join Point, Pointcut, Advice
- 활용 사례: 로깅, 보안, 트랜잭션 관리, 성능 모니터링
- 장점: 코드 중복 제거, 유지보수성 증가
- 단점: 복잡성 증가, 디버깅 어려움
출처 : ChatGPT
'BE > Spring & Spring Boot' 카테고리의 다른 글
[Spring Boot] @ControllerAdvice (0) | 2025.01.09 |
---|---|
[Spring Boot] PSA (0) | 2025.01.05 |
[Spring Boot] DTO (0) | 2025.01.04 |
[Spring Boot, JPA] 관련 어노테이션 (0) | 2025.01.01 |
[Spring Boot] 관련 어노테이션 (0) | 2025.01.01 |