본문 바로가기
스프링 부트3

스프링 부트 3의 AOP 기본 사용법

by 굿센스굿 2024. 12. 4.
반응형

 

AOP(Aspect-Oriented Programming)는 관심사를 분리(Separation of Concerns)하여 코드의 모듈성을 높이는 강력한 프로그래밍 패러다임입니다. 스프링 부트 3에서는 AOP를 쉽게 설정하고 사용할 수 있는 환경을 제공합니다. 이번 글에서는 스프링 부트 3에서 AOP의 기본 사용법을 단계별로 설명하고, 실무에서 활용 가능한 예제 3가지를 소개하겠습니다.


1. AOP란 무엇인가?

AOP의 개념

AOP는 비즈니스 로직과는 별개로 공통적으로 적용되어야 하는 기능(로깅, 트랜잭션 관리 등)을 분리하여 작성할 수 있게 도와줍니다. 스프링에서 AOP는 @Aspect 어노테이션과 포인트컷(Pointcut), 어드바이스(Advice)를 사용하여 구현합니다.

AOP의 주요 용어

  • Aspect: 공통 관심사를 정의한 모듈.
  • Advice: Aspect에서 실행되는 코드. 실행 시점에 따라 Before, After, Around 등으로 구분됩니다.
  • Pointcut: Advice가 적용될 대상(메서드나 클래스)을 정의.
  • Join Point: Advice가 적용 가능한 실행 지점.
  • Weaving: Aspect와 비즈니스 로직을 결합하는 과정.

2. 스프링 부트 3에서 AOP 설정

2.1 의존성 추가

스프링 부트 프로젝트에서 AOP를 사용하려면 spring-boot-starter-aop 의존성을 추가해야 합니다.

build.gradle

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-aop'
}

2.2 AOP 기본 설정

AOP를 사용하기 위해 @Aspect 어노테이션을 사용하여 Aspect 클래스를 생성하고, @EnableAspectJAutoProxy를 활성화합니다.
스프링 부트는 자동으로 AOP를 활성화하므로 별도 설정 없이도 사용 가능합니다.


3. AOP 적용 단계

3.1 간단한 로깅 Aspect 구현

1단계: Aspect 클래스 생성

아래는 메서드 호출 전후로 로깅을 추가하는 간단한 예제입니다.

import org.aspectj.lang.annotation.*;
import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

    @Around("execution(* com.example.service..*(..))") // 서비스 패키지의 모든 메서드
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object proceed = joinPoint.proceed();
        long executionTime = System.currentTimeMillis() - start;

        logger.info("{} executed in {} ms", joinPoint.getSignature(), executionTime);
        return proceed;
    }
}
  • @Around: 메서드 실행 전후를 감싸는 Advice.
  • execution: 포인트컷 표현식으로, 특정 패키지나 메서드에만 적용합니다.

2단계: 서비스 클래스 생성

AOP가 적용될 대상인 비즈니스 로직을 작성합니다.

import org.springframework.stereotype.Service;

@Service
public class SampleService {

    public String process() {
        // 비즈니스 로직
        return "Processing Complete!";
    }
}

3단계: 애플리케이션 실행

서비스 메서드를 호출하면 AOP가 동작하여 실행 시간 로그를 출력합니다.


4. 실무 활용 예제

예제 1: 메서드 실행 시간 측정

위에서 작성한 LoggingAspect를 활용하면, 메서드 실행 시간을 측정하여 성능 최적화에 도움을 줄 수 있습니다.

실행 결과 예시

INFO  c.e.LoggingAspect - SampleService.process executed in 123 ms

예제 2: 권한 검증 Aspect

메서드 실행 전에 사용자의 권한을 확인하는 로직을 추가할 수 있습니다.

권한 검증 Aspect

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class SecurityAspect {

    @Before("execution(* com.example.controller..*(..))")
    public void checkUserPermission() {
        // 권한 검증 로직
        System.out.println("Checking user permissions...");
    }
}

실행 흐름

컨트롤러 메서드 호출 시, 권한 검증이 선행됩니다.


예제 3: 트랜잭션 상태 로깅

트랜잭션이 시작되고 종료될 때 로그를 남기는 Aspect를 구현할 수 있습니다.

트랜잭션 Aspect

import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TransactionAspect {

    @Before("execution(* com.example.service..*(..))")
    public void beforeTransaction() {
        System.out.println("Transaction Started");
    }

    @After("execution(* com.example.service..*(..))")
    public void afterTransaction() {
        System.out.println("Transaction Ended");
    }
}

5. AOP 사용 시 주의사항

  1. 포인트컷 범위 관리: 포인트컷 범위를 지나치게 넓게 설정하면 불필요한 메서드에 AOP가 적용될 수 있습니다.
  2. 성능 고려: AOP를 과도하게 사용하면 애플리케이션 성능에 영향을 미칠 수 있습니다.
  3. 디버깅 복잡성: AOP로 인해 실제 실행 흐름이 복잡해질 수 있으므로 디버깅 시 주의가 필요합니다.

6. 결론

스프링 부트 3의 AOP는 간단한 설정만으로 로깅, 권한 검증, 트랜잭션 관리 등 다양한 공통 관심사를 처리할 수 있는 강력한 도구입니다. 이번 글에서 소개한 기본 사용법과 예제를 기반으로 실제 프로젝트에 적용해 보세요.
추가 질문이나 확장 주제가 있다면 댓글로 남겨주세요! 😊

반응형