Spring

[Spring] Spring AOP 개념

아윤_ 2025. 4. 28. 16:03

AOP란?

 

AOP

  • Aspect Oriented Programming의 약어
  • 핵심 비즈니스 로직과 횡단 관심사를 분리하여 모듈화, 유지보수성과 재사용성 향상
  • 횡단 관심사: 로깅, 트랜잭션 관리 등 여러 모듈에서 공통으로 처리해야 하는 기능

 

 

주요 개념

 

Aspect

공통 관심사를 구현한 모듈

 

Join Point

메서드 호출 시점, 예외 발생 지점 등

 

Advice

Aspect에서 실행될 구체적 동작을 정의하는 부분으로 언제, 어떤 동작을 수행할지 결정

  • @Before: 타겟 메서드 실행 전 동작
  • @After: 타겟 메서드 실행 후 동작
  • @AfterReturning: 메서드 정상 반환 후 동작
  • @AfterThrowing: 메서드 예외 발생 시 동작
  • @Around: 메서드 실행 전후 동작 제어, 직접 호출도 가능

 

Pointcut

Advice를 적용할 Join Point를 선별하기 위한 표현식

 

Weaving

Aspect와 Advice를 실제 객체에 적용하는 과정을 지칭

 

 

Spring AOP 특징

 

스프링 빈에만 적용

  • 기본적으로 스프링 컨테이너에 등록된 빈에만 AOP가 적용됨

 

프록시 기반 구현

  • JDK 동적 프록시 또는 CGLIB 기반 프록시를 사용하여 런타임에 Advice를 대행
  • 인터페이스가 있는 경우 JDK 동적 프록시를 우선으로 하고, 그렇지 않을 경우 CGLIB를 활용

 

경량화, 선언적

  • XML 설정 또는 어노테이션 기반 선언형 프로그래밍 지원
  • 애플리케이션 로직과 설정 완전 분리

 

제한 사항

  • public 메서드에만 적용
  • 같은 클래스 내에서 자가호출 하는 경우에는 프록시를 경유하지 않아 Advice가 적용되지 않음

 

 

Spring AOP 적용 방식 비교

방식 장점 단점 권장 여부
XML 방식 설정 분리, 중앙 관리 용이 설정 가독성 떨어짐, 장황 △ (유지보수 비추천)
어노테이션 방식 코드와 설정 동시 관리, 직관적 코드와 설정 혼합, 분리도 감소 ✅ (추천)
AspectJ weaving 방식 가장 강력, 메서드 내부 호출까지 적용 빌드 복잡, 학습 곡선 높음 △ (필요 시만 권장)

 

어노테이션 기반 AOP 사용법

 

사용자 정의 어노테이션 만들기

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogExcutionTime {
}

 

Aspect 클래스 작성

@Component
@Aspect
public class SimpleLogAspect {
	// 특정 어노테이션이 붙은 메서드에 AOP 적용
	@Around("@annotation(com.example.annotation.LogExcutionTime)")
	public Object logTime(ProceedingJoinPoint pjp) throws Throwable {
		long start = System.currentTimeMillis();
		
		Object result = pjp.proceed(); // 원래 메서드 실행
		
		long excutionTime = System.currentTimeMillis() - start;
        System.out.println(joinPoint.getSignature() + " 실행 시간: " + executionTime + "ms");
    
		return result;    
		
	}
}
  • @Aspect: 해당 클래스가 AOP Aspect임을 표시
  • @Component: 스프링 빈 등록
  • @Around: 실행 전후 Advice를 정의, ProceedingJoinPoint.proceed()로 원본 메서드 실행

 

타겟 메서드에 어노테이션 적용

@Service
public class DemoService {

	@LogExcutionTime
	public void excuteJob() throws InterruptedException {
		Thread.sleep(500);
	  System.out.println("executeJob 메서드 실행됨.");
	}
}

 

실행 결과

executeJob 메서드 실행됨.
void com.example.DemoService.executeJob() 실행 시간: 503ms

 

정리

  • AOP는 횡단 관심사를 분리하여 핵심 로직을 깔끔하게 유지한다.
  • Spring AOP는 프록시 기반으로 간편하게 선언적 적용이 가능하다.
  • 어노테이션 방식이 유지보수와 가독성 측면에서 가장 널리 사용된다.
  • 트랜잭션 보안, 로깅 등 다양한 분야에 응용 가능하다.