복잡한뇌구조마냥

[JAVA] AOP (관점 지향 프로그래밍) 기초 정리 본문

BE/JAVA

[JAVA] AOP (관점 지향 프로그래밍) 기초 정리

지금해냥 2025. 8. 22. 14:50

1. AOP란?

  • Aspect Oriented Programming (관점 지향 프로그래밍)
  • 핵심 로직(비즈니스)과 부가 로직(공통 관심사: 로깅, 보안, 트랜잭션 등)을 분리하는 기법
  • OOP(객체지향 프로그래밍)를 보완하는 개념

👉 핵심 아이디어: “횡단 관심사(Cross-cutting concern)를 모듈화하자”


2. AOP가 필요한 이유

예를 들어 서비스 메서드마다 실행 시간 측정을 넣고 싶다고 할 때:

AOP 적용 전 (중복 코드 발생)

 
public void createMember() {
    long start = System.currentTimeMillis();
    // 비즈니스 로직
    long end = System.currentTimeMillis();
    System.out.println("실행 시간: " + (end - start));
}

AOP 적용 후 (공통 로직 분리)

 
@LogExecutionTime
public void createMember() {
    // 비즈니스 로직만 남김
}

3. Spring에서 AOP 사용법

의존성 (Gradle)

 
implementation("org.springframework.boot:spring-boot-starter-aop")

4. 핵심 용어

  • Aspect: 공통 기능을 모듈화한 클래스 (@Aspect)
  • Advice: 언제 실행할지 정의 (Before, After, Around 등)
  • Join Point: AOP 적용 가능한 지점 (메서드 실행 시점 등)
  • Pointcut: 실제로 AOP를 적용할 지점 지정 (execution(...))
  • Weaving: 핵심 로직 + 부가 로직 결합하는 과정

5. 예제: 실행 시간 로깅

 
@Aspect
@Component
public class LogAspect {

    @Around("execution(* com.example.service..*(..))")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();

        Object proceed = joinPoint.proceed(); // 실제 메서드 실행

        long end = System.currentTimeMillis();
        System.out.println(joinPoint.getSignature() + " 실행 시간: " + (end - start) + "ms");

        return proceed;
    }
}
  • @Around: 메서드 실행 전후 모두 제어 가능
  • "execution(* com.example.service..*(..))": service 패키지 아래 모든 메서드 대상

6. Advice 종류

종류 설명 어노테이션
Before 메서드 실행 전 @Before
AfterReturning 정상 종료 후 @AfterReturning
AfterThrowing 예외 발생 시 @AfterThrowing
After 메서드 종료 후(성공/실패 무관) @After
Around 전/후 모두 (가장 강력) @Around

7. 애노테이션 기반 Pointcut

 
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime { }
@Aspect
@Component
public class AnnotationAspect {
    @Around("@annotation(com.example.LogExecutionTime)")
    public Object log(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = pjp.proceed();
        long end = System.currentTimeMillis();
        System.out.println("실행 시간: " + (end - start) + "ms");
        return result;
    }
}

→ 원하는 메서드에만 @LogExecutionTime 붙이면 적용 가능


8. 실무 활용 예시

  • 로깅(Log): 요청/응답 로그, 실행 시간 추적
  • 보안(Security): 접근 제어, 인증/인가 처리
  • 트랜잭션 관리: @Transactional 내부적으로 AOP 활용
  • 캐싱(Cache): 메서드 결과 캐싱

9. 장단점

✅ 장점

  • 공통 관심사 분리 → 코드 중복 감소
  • 핵심 비즈니스 로직이 깔끔해짐
  • 유지보수/확장성 향상

❌ 단점

  • 남용 시 흐름 파악 어려움
  • 디버깅 난이도 ↑ (숨은 동작이 많아짐)

10. 마무리

Spring AOP는 실무에서 트랜잭션(@Transactional), 로그/보안 처리 등에 이미 광범위하게 쓰이고 있습니다.
직접 어노테이션 + @Aspect 조합을 써보면, 프레임워크 내부 동작 원리를 이해하는 데 큰 도움이 됩니다.

LIST