AOP(Aspect-Oriented Programming, 관점 지향 프로그래밍)는 개발자가 횡단 관심사를 모듈화하고
주요 비즈니스 로직에서 분리할 수 있게 하는 강력한 프로그래밍 패러다임입니다.
여기서 AOP의 기본 개념, 스프링 프레임워크에서의 구현 방법, 그리고 이점을 잘 보여주는 실용적인 예제를 통해 AOP를 살펴볼 것입니다.
AOP란 무엇인가?
AOP는 객체 지향 프로그래밍(OOP)을 보완하여
로깅, 보안, 트랜잭션 관리 등과 같은 횡단 관심사를 주 비즈니스 로직으로부터 분리할 수 있게 해줍니다.
AOP는 이러한 관심사를 별도의 모듈인 "Aspect"로 캡슐화하여 코드의 장황함을 줄이고 유지보수성을 높이는 데 도움을 줍니다.
AOP의 핵심 개념
Aspect(관점): 횡단 관심사를 캡슐화한 모듈 (예: 로깅)
Join Point(조인 포인트): Aspect가 적용될 수 있는 프로그램 실행 지점 (예: 메서드 실행)
Advice(어드바이스): 특정 조인 포인트에서 Aspect에 의해 취해지는 행동. Before, After, Around 등이 있습니다.
Pointcut(포인트컷): Advice가 적용될 조인 포인트를 매칭하는 표현식입니다.
Target Object(대상 객체): Advice가 적용되는 대상 객체입니다.
AOP Proxy(AOP 프록시): AOP 프레임워크는 Target Object에 대한 Proxy를 생성하여, Advice를 Join Point에 적용합니다.
저도 처음에는 단어들이 생소했지만, 예제들을 보니 이해가 되었습니다.
예제를 바로 들어가보죠!
예제: 로그인 상태 확인을 위한 AOP 구현
이 예제에서는 스프링 프레임워크를 사용하여 사용자의 로그인 상태를 확인하는 간단한 AOP를 구현해보겠습니다.
이 AOP는 특정 메서드에 액세스하기 전에 사용자가 로그인했는지 여부를 확인합니다.
// LoginCheck.java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LoginCheck {
}
// LoginCheckAspect.java
@Aspect
@Component
public class LoginCheckAspect {
@Around("@annotation(com.example.LoginCheck)")
public Object checkLoginStatus(ProceedingJoinPoint joinPoint) throws Throwable {
// 로그인 상태 확인 로직
// 예: 세션에서 사용자 정보 가져오기
// 로그인 상태가 아니면 예외 발생
return joinPoint.proceed(); // 로그인 상태이면 원래 메서드 실행
}
}
// UserService.java
public class UserService {
@LoginCheck
public User getUserDetails(String userId) {
// 사용자 정보 조회 로직
}
}
핵심 개념을 기준으로 정리 해볼게요!
Aspect (관점)
LoginCheckAspect 클래스가 Aspect입니다.
이 클래스는 보안 관련 횡단 관심사(로그인 상태 확인)를 모듈화합니다.
Join Point (조인 포인트)
LoginCheck 어노테이션이 적용된 메서드 호출이 Join Point입니다.
프로그램 실행 중 @LoginCheck가 붙은 메서드가 호출될 때마다, 이를 Aspect에서 가로챌 수 있는 지점이 됩니다.
Advice (어드바이스)
LoginCheckAspect 클래스의 checkLoginStatus 메서드가 Advice입니다.
@Around 어노테이션으로 정의된 이 메서드는
Join Point(여기서는 @LoginCheck 어노테이션이 적용된 메서드)에서 실행됩니다.
Before Advice: checkLoginStatus 메서드는 원래의 메서드 실행 전에 로그인 상태를 확인합니다.
Around Advice: checkLoginStatus 메서드는 원래의 메서드를 감싸서 실행하며, 로그인 상태에 따라 원래 메서드의
실행을 계속하거나 중단시킵니다.
Pointcut (포인트컷)
@Around("@annotation(com.example.LoginCheck)")는 Pointcut을 정의합니다.
이 표현식은 @LoginCheck 어노테이션이 적용된 모든 메서드를 Advice의 대상으로 지정합니다.
Target Object (대상 객체)
UserService의 getUserDetails 메서드가 Target Object의 예입니다.
이 메서드에 @LoginCheck 어노테이션이 적용되어 있어, LoginCheckAspect의 Advice가 이 메서드에 적용됩니다.
AOP Proxy (AOP 프록시)
스프링 프레임워크는 내부적으로 UserService의 getUserDetails 메서드에 대한 프록시를 생성합니다.
이 프록시는 @LoginCheck 어노테이션이 적용된 메서드 호출 시 LoginCheckAspect의 Advice를 실행합니다.
결론
예제를 통해, AOP를 사용하면 로그인 확인과 같은 보안 관련 로직을 비즈니스 로직으로부터 분리하여 관리할 수 있음을 볼 수 있습니다.
LoginCheckAspect는 모든 @LoginCheck 어노테이션이 적용된 메서드에 대해 로그인 상태를 확인하는 공통 기능을 제공합니다.
이는 코드의 재사용성을 높이고, 유지보수성을 향상시키며, 각 부분의 관심사를 명확하게 분리하는 효과를 가져옵니다.
참고자료
토비의 스프링 부트
'스프링&스프링부트' 카테고리의 다른 글
[Spring]Spring 개발자를 위한 Annotation 원리와 커스텀 Annotation 실습 (0) | 2025.01.18 |
---|---|
[Spring] yml 암호화를 해보자(feat. jasypt) (2) | 2024.01.03 |
[Spring] 메세지 컨버터란 (Spring message converter) (5) | 2023.11.01 |
[Spring] validation @NotNull @NotEmpty @NotBlank (0) | 2023.10.24 |