💡 Spring AOP는 “포인트컷 표현식”이 해당 Advice 메서드에만 매핑된다?
@Before("@annotation(com.example.CheckSomething) && args(email)")
public void checkSomething(String email) { ... }
이렇게 포인트컷을 작성하면, Spring은 이 포인트컷을 이 Advice 메서드 하나에만 적용.
✅ 포인트컷(Pointcut) 이란?
AOP에서 “어떤 메서드에 Advice(전처리, 후처리 등)를 적용할지 지정하는 조건”
@Before("@annotation(CheckUserDeleted) && args(email)")
public void checkUserDeleted(String email) { ... }
🧠 “CheckUserDeleted 어노테이션이 붙고, 첫 번째 인자가 email인 메서드에 이 checkUserDeleted() 메서드를 실행 전에 자동으로 적용하라는 뜻!”
❗그런데 문제는?
Spring AOP는 미리 컴파일 타임에 “이 Advice가 어디에 적용될지” 검사
- args(email) 이라는 조건은:
- “어노테이션이 붙었고, 첫 번째 인자가 email인 메서드”를 찾겠다는 뜻
- 그런데 그런 메서드가 코드에 없으면?
- “적용할 메서드가 없네? → 이 Advice 쓸모없음” → 경고
📘 그래서 말한 뜻 다시 해석
하나의 포인트컷 표현식은그 포인트컷 조건에 맞는 Advice 메서드에만 적용되기 때문에 조건을 만족하는 메서드가 없으면 경고가 뜸
그럼 왜 args(email), args(userId) 등으로 Advice를 여러 개 만들면 IntelliJ가 경고를 줄까?
🔥 진짜 핵심 포인트!
Spring AOP는 포인트컷 조건 하나하나가 적용될 메서드가 반드시 실제로 있어야 함.
Spring AOP는 args(...)에서 매개변수 순서, 개수, 이름까지 엄격하게 따짐!
🧨 실제 서비스 메서드 시그니처:
→ 이건 인자가 2개임!
public void deleteUser(Long userId, String password)
근데 AOP Advice는:
@Before("@annotation(CheckUserDeleted) && args(userId)")
public void checkUserDeletedById(Long userId)
→ 이건 “인자가 딱 하나”일 때만 매칭!
❗ 그래서 이 포인트컷은 args(userId)만 있을 때만 동작하고, args(userId, password) 같은 메서드는 매칭이 안 돼버려서 경고가 뜬 것
예시 상황 정리
@Before("@annotation(CheckUserDeleted) && args(email)")
public void checkEmail(String email) { ... }
@Before("@annotation(CheckUserDeleted) && args(userId)")
public void checkId(Long userId) { ... }
@Before("@annotation(CheckUserDeleted) && args(requestDto)")
public void checkDto(SignUpRequestDto requestDto) { ... }
😵 그런데 현재 프로젝트에 이런 메서드가 없다면?
@CheckUserDeleted
public void someMethod(Double money) // ❌ 조건 불일치
해결 방법
✅ Advice 통합 (추천)
args(arg,..)로 받고 instanceof로 분기
@Before("@annotation(com.example.yamyam16.auth.common.annotation.CheckUserDeleted) && args(arg,..)")
public void checkUserDeleted(Object arg) {
if (arg instanceof String email) {
checkDeletedByEmail(email);
} else if (arg instanceof Long userId) {
checkDeletedByUserId(userId);
} else if (arg instanceof SignUpRequestDto dto) {
checkDeletedByEmail(dto.getEmail());
} else if (arg instanceof LoginRequestDto dto) {
checkDeletedByEmail(dto.getEmail());
}
}
'코딩 > sparta TIL' 카테고리의 다른 글
TIL 40 : JPA 심화 - 프로젝트별 의존성 설명 (0) | 2025.05.01 |
---|---|
TIL 39 : 영속성 컨텍스트 - 준영속을 하는 이유 😇 (0) | 2025.04.30 |
TIL 37 : Optional, 람다식, instanceof (0) | 2025.04.24 |
TIL 36 : EntityManagerFactory, EntityManager, EntityTransaction (1) | 2025.04.16 |
TIL 35 : 예외처리 복습 (1) | 2025.04.15 |