Spring

[Spring] Spring AOP로 Log 기록하기 : @Around / @Before / @After

s_ih_yun 2025. 9. 9. 23:46
728x90

 

 

 

 

 

1. Spring AOP

  • AOP (Aspect-Oriented Programming) : 관점 지향 프로그래밍을 지원하는 기술
  • 로깅, 보안, 트랜잭션 관리 등과 같은 공통 관심사를 모듈화
    • 코드 중복을 줄이고 유지 보수성 향상
  • 핵심 로직과 부가 기능 분리

 

 

1.1. 주요 용어

용어 설명
Aspect 공통적인 기능들을 모듈화한 것을 의미
Target Aspect가 적용될 대상 (메소드, 클래스 등이 해당)
Join point Aspect가 적용될 수 있는 시점 (메소드 실행 전, 후 등)
Advice Aspect의 기능을 정의한 것
Point cut Advice를 적용할 메소드의 범위를 지정

 

 

1.2. 주요 어노테이션

어노테이션 설명
@Aspect 해당 클래스를 Aspect로 사용하겠다는 명시
@Before 대상 메소드가 실행되기 전에 Advice 실행
@AfterReturning 대상 메소드가 정상적으로 실행되고 반환된 후 Advice 실행
@AfterThrowing 대상 메소드에서 예외가 발생했을 때 Advice 실행
@After 대상 메소드가 실행된 후에 Advice 실행
@Around 대상 메소드 실행 전, 후 또는 예외 발생 시 Advice 실행

 

 

 

 

 

 

 

2. Spring AOP로 Log 기록하기

 

2.1. Spring AOP 환경 설정

  • build.gradle에 의존성 추가
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-aop'
}

 

 

 

2.2. AOP 클래스 작성

 

2.2.1. @Before / @After : 메소드 호출 전 / 후 로깅

package com.syun.posleep.aspects;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect
@Component
public class ApiLoggingAspect {

    @Pointcut("execution(* com.syun.posleep.web..*(..))")   // 적용 범위 정의
    public void controller() {
    }
    
    /* 메소드 호출 전 실행 */
    @Before("controller()")
    public void logBeforeTest(JoinPoint joinPoint) throws Throwable {
        log.info("Controller Before");
    }
    
    /* 메소드 호출 후 실행 */
    @After("controller()")
    public void logAfterTest(JoinPoint joinPoint) throws Throwable {
        log.info("Controller After");
    }
}
  • JoinPoint : Aspect가 적용될 시점을 의미
    • 호출되는 대상 객체, 메서드, 전달 파라미터 목록에 접근 가능한 메서드 제공
  • Log

 

 

2.2.2. @Around : 메소드 호출 전 / 후 / 예외상황 로깅

package com.syun.posleep.aspects;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect
@Component
public class ApiLoggingAspect {

    @Pointcut("execution(* com.syun.posleep.web..*(..))")
    public void controller() {
    }

    @Around("controller()")
    public Object logAroundTest(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("Controller Before - Around");       // 메소드 호출 전
        try {
            Object result = joinPoint.proceed();
            log.info("Controller Success - Around");  // 메소드 호출 후(성공)
            return result;
        } catch (Throwable e) {
            log.info("!! Controller Fail - Around");  // 메소드 호출 후(예외발생)
            throw e;
        }
    }
}
  • Proceeding JoinPoint : JoinPoint를 상속 받아 추가 기능을 제공
    • @Around에서만 지원
    • proceed() 메소드를 통해 target 실행제어가 가능 (반드시 호출해야 타겟이 실행 가능)
    • 반드시 Object를 리턴
      • 타겟 메소드가 리턴하는 값을 그대로 반환
      • void를 리턴타입으로 할 경우 : 타겟의 응답이 사라져 API가 동작하지 않음

 

 

 

 

 

 

 

 


📌 References

https://adjh54.tistory.com/133

https://velog.io/@youjung/Spring-AOP

https://velog.io/@jjeongdong/Spring-AOP를-활용한-Logging-구현

https://ivory-room.tistory.com/86

 

 

 

 

 

 

 

 

728x90