25.03.10 TIL Spring AOP

신성훈·2025년 3월 10일

TIL

목록 보기
144/162

1. AOP란?

AOP(Aspect-Oriented Programming, 관점 지향 프로그래밍)는 공통된 기능(로깅, 트랜잭션, 보안 등)을 분리하여 코드의 중복을 줄이고 유지보수를 용이하게 하는 기법이다.
Spring에서는 Spring AOP를 통해 AOP 기능을 지원한다.


2. AOP의 주요 개념

Spring AOP에서는 다음과 같은 핵심 개념이 존재한다.

  1. Aspect (관점, 단면)

    • 공통 기능(트랜잭션, 로깅, 보안 등)이 구현된 모듈
  2. Advice (충고, 기능 구현부)

    • Aspect에서 실행할 구체적인 기능
    • 종류: Before, After, AfterReturning, AfterThrowing, Around
  3. Pointcut (접점, 적용 위치 설정)

    • Aspect를 적용할 메서드 또는 클래스의 위치 지정
  4. JoinPoint (연결 지점)

    • Advice가 실행될 수 있는 시점 (메서드 호출, 예외 발생 등)
  5. Weaving (위빙)

    • Aspect를 대상 객체에 적용하는 과정 (컴파일 시, 런타임 시 가능)

3. Spring AOP 설정 및 사용

AOP 의존성 추가

Spring Boot 프로젝트에서 AOP를 사용하려면 spring-boot-starter-aop 의존성을 추가해야 한다.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

Aspect 구현

@Aspect
@Component
public class LoggingAspect {
    
    @Before("execution(* com.example.service.*.*(..))")
    public void beforeMethodExecution(JoinPoint joinPoint) {
        System.out.println("[Before] 메서드 실행: " + joinPoint.getSignature().getName());
    }
    
    @AfterReturning("execution(* com.example.service.*.*(..))")
    public void afterReturningMethod(JoinPoint joinPoint) {
        System.out.println("[AfterReturning] 메서드 성공: " + joinPoint.getSignature().getName());
    }
    
    @AfterThrowing("execution(* com.example.service.*.*(..))")
    public void afterThrowingMethod(JoinPoint joinPoint) {
        System.out.println("[AfterThrowing] 예외 발생: " + joinPoint.getSignature().getName());
    }
}
  • @Before : 메서드 실행 전에 실행됨
  • @AfterReturning : 메서드가 정상적으로 실행된 후 실행됨
  • @AfterThrowing : 예외 발생 시 실행됨

Pointcut 표현식 예제

@Pointcut("execution(* com.example.service.UserService.*(..))")
public void userServiceMethods() {}
  • execution(* 패키지명.클래스명.메서드명(..)) 형식으로 특정 메서드에 적용 가능
@Before("userServiceMethods()")
public void logBeforeUserServiceMethods(JoinPoint joinPoint) {
    System.out.println("[Before] UserService 메서드 호출: " + joinPoint.getSignature().getName());
}
  • @Pointcut을 활용하여 여러 곳에서 공통적으로 사용할 수 있음

4. AOP의 주요 활용 사례

  • 로깅(Loggin): 모든 메서드 호출 시 로그를 남기기
  • 트랜잭션(Transaction Management): @Transactional을 통한 트랜잭션 관리
  • 보안(Security): 특정 메서드 실행 전에 사용자 인증 확인
  • 성능 모니터링(Performance Monitoring): 실행 시간 측정

5. AOP 사용 시 주의할 점

  1. Spring AOP는 기본적으로 프록시 기반으로 동작하기 때문에, private 메서드에는 적용되지 않음
  2. 같은 클래스 내에서 호출하는 메서드는 AOP 적용이 되지 않을 수 있음
    (자기 자신을 호출하는 경우 프록시를 거치지 않기 때문)
  3. Aspect의 남용은 코드 가독성을 떨어뜨릴 수 있으므로 필요한 곳에만 적용해야 함

6. 마무리

Spring AOP를 사용하면 코드의 중복을 줄이고 로깅이나 트랜잭션 관리 같은 공통 관심 사항을 분리할 수 있어 유지보수가 편리하다. 특히 @Transactional처럼 자동으로 트랜잭션을 관리해 주는 기능도 AOP 기반이라는 점이 흥미로웠다.
AOP 남용 시 코드가 복잡해질 수 있으므로 적절한 범위에서 적용하는 것이 중요하다는 점을 다시 한번 느꼈다.

profile
조급해하지 말고, 흐름을 만들고, 기록하면서 쌓아가자.

0개의 댓글