관점 지향 프로그래밍 (Aspect Oriented Programming)
어떤 로직을 기준으로 "핵심적인 관점"과 "부가적인 관점"으로 나누어 보고 그 관점들을 기준으로 모듈화를 하겠다는 의미이다.
핵심적인 관점: 핵심 비즈니스 로직
부가적인 관점: 핵심 비즈니스 로직을 달성하기 위해 필요한 데이터베이스 연결, 로깅 등
**"부가적인 관점"**의 특징으로 코드 상에서 여러 곳에서 반복해서 사용되는데 이를 흩어진 관심사(Crosscutting Concerns)라고 말하고 이반복되고 있는 흩어진 관심사를 모듈화하여 재사용하겠다는 취지이다.
| 용어 | 설명 |
|---|---|
| Aspect | 흩어진 관심사를 모듈화한 것(데이터베이스 연결, 로깅 등) |
| Pointcut | 어떤 Join Point에 Advice를 적용할 지 결정하는 방법을 정의 |
| Advice | Aspect의 기능을 정의한 것으로 메소드 실행 전, 후, 예외 처리 발생 등 실행 시점을 선언 |
| Join Point | Aspect를 적용할 수 있는 프로그램의 특정 지점(메서드 호출, 객체 생성 등) |
dependencies {
// ...
implementation 'org.springframework:spring-aspects'
// ...
}- 비즈니스 로직(서비스 레이어드)
package com.example.funch.order;
// import ... 생략
@Service
public class OrderService {
public String purchase(String userId) {
// 복잡한 비즈니스 로직
return puchaseId;
}
}- 새로운 요구사항 발생
- 1) 사용자 구매 행위에 대해 로그 출력
- 2) 알림 발송
- AOP 적용
1) 사용자 구매 행위 로그 출력을 위한 Aspect
package com.example.funch.order.aop;
// import ... 생략
@Component
@Aspect // 부가 관심사 등록
public class OrderActionAspect {
// Around: Advice 옵션
// execution: Point Cut 옵션
@Around("execution(* com.example.funch.order.OrderService.purchase(..))")
public Object printLog(ProceedingJoinPoint jointPoint) throws Throwable {
// 사용자 행위에 대한 로그 출력 또는 저장 로직
return joinPoint.proceed();
}
}2) 사용자 구매 알림 발송 Aspect
package com.example.funch.order.aop;
// import ... 생략
@Component
@Aspect // 부가 관심사 등록
public class OrderNotificationAspect {
// AfterReturning: Advice 옵션
// execution: Point Cut 옵션
@AfterReturning(
pointcut = "execution(* com.example.funch.order.OrderService.purchase(...))",
returning = "result"
)
public void send(JoinPoint joinPoint, String result) {
// 사용자 구매 알림 발송 로직
}
}간단하게 흐름만 정리했을 때에는 위와 같은 흐름으로 Aspect를 생성한다.
