
우연히 Velog 포스트를 보다가 AOP라는 생소한 단어를 접하게 되었다. 이에 대해 알아보고 정리하는 시간을 가져보려고 한다.
AOP(Aspect-Oriented Programming)는 관점 지향 프로그래밍. 프로그램의 핵심 비즈니스 로직과 공통적으로 사용되는 기능(횡단 관심사, Cross-cutting Concern) 을 분리해서 관리하는 프로그래밍 패러다임.
AOP의 핵심 개념 중 하나인 횡단 관심사(Cross-cutting Concern)는 애플리케이션의 여러 부분에서 공통적으로 필요한 기능을 의미.
즉, 핵심 기능과 직접적인 관련은 없지만 필수적인 기능이 횡단 관심사.
비즈니스 로직에 직접 관여하지 않음
- AOP는 핵심 비즈니스 로직과 별도로 동작하며, 코드 내부에서 직접 호출되지 않음.
- 주요 기능(예: 회원 가입, 주문 처리 등)과 보조 기능(로깅, 보안 검사 등)을 분리하여 가독성을 높임.
소스 코드 수정 없이 기능 추가 가능
- 기존 비즈니스 로직을 수정하지 않고도 새로운 기능을 추가할 수 있음.
- 예를 들어, 로깅 기능을 추가하려면 각 메서드에 console.log()를 넣는 대신, AOP를 활용해 모든 메서드 실행 시 자동으로 로깅할 수 있음.
자동으로 실행됨 (개발자가 직접 호출할 필요 없음)
- AOP는 미리 정의된 규칙(Pointcut)에 따라 자동으로 적용됨.
- 개발자가 직접 관련 로직을 호출할 필요 없이, 특정 조건을 만족하는 경우 자동으로 실행됨.
반복적인 기능을 모듈화하여 유지보수 용이
- 공통적으로 사용되는 기능을 한 곳(Aspect)에서 관리하여 코드 중복을 최소화하고 유지보수를 쉽게 함.
- ✅ 로깅(Logging) - 특정 메서드 실행 정보를 자동으로 기록
- ✅ 트랜잭션 관리(Transaction Management) - 데이터 변경 작업에서 오류 발생 시 롤백 처리
- ✅ 유효성 검사(Validation) - API 요청 데이터의 형식 및 값 검증
- ✅ 보안(Security) - 사용자의 권한 확인 후 요청을 처리
// 사용하려는 아이템 목록을 검증하고 구한다.
$items = app(InventoryService::class)->getAndVerifyItems(
itemsRequest: $request->items,
functionGroup: '먹이',
);
비즈니스로직 ....
아이템 사용시 공통적으로 수행되는 로직
public function getAndVerifyItems(
array $itemsRequest,
string $functionGroup = '',
)
{
/** @var Collection<int, MemberInventory> $itemsResult */
$itemsResult = MemberInventory::whereIn('GMI_IDX', array_column($itemsRequest, 'inventoryId'))->get();
$items = [];
foreach ($itemsRequest as ['inventoryId' => $inventoryId, 'quantity' => $quantity]) {
/** @var MemberInventory */
$item = $itemsResult->firstWhere('GMI_IDX', $inventoryId);
if (!$item) {
throw new NotFoundHttpException('id ' . $inventoryId . ' 아이템이 없습니다.');
}
if ($item->MEMBER_IDX !== auth()->user()->MEMBER_IDX) {
throw new AccessDeniedHttpException('id ' . $inventoryId . ' 아이템에 대한 권한이 없습니다.');
}
if ($item->GMI_QTY < $quantity) {
throw new UnprocessableEntityHttpException('id ' . $inventoryId . ' 아이템 수량이 부족합니다.');
}
if ($functionGroup && $item->Item->GI_GROUP_FUNCTION !== $functionGroup) {
throw new BadRequestHttpException($functionGroup . ' 아이템만 사용할 수 있습니다.');
}
$items[] = $item;
}
return collect($items);
}