Spring AOP 사용 시 내부 호출 문제
Spring AOP를 사용할 때 내부 호출 문제는 AOP가 적용된 프록시를 통해 대상 객체(Target)를 호출해야 발생하는데, 프록시를 거치지 않고 직접 호출하면 AOP가 적용되지 않아 어드바이스가 호출되지 않는 문제가 생깁니다.
이 문제는 @Transactional과 같은 AOP 기반 기능에서도 동일하게 발생합니다.
해결 방법으로는 대상 객체를 직접 호출해서 발생한 문제이기 때문에 외부 호출을 하면 문제가 해결됩니다.
해결 방법 - 지연 조회
내부 호출을 사용한 예시
@Slf4j
@Component
public class CallServiceV0 {
public void external() {
log.info("call external");
internal(); // 내부 호출
}
public void internal() {
log.info("call internal");
}
}
ApplicationContext, ObjectProvider를 사용
@Slf4j
@Component
@RequiredArgsConstructor
public class CallServiceV2 {
1-1 private final ApplicationContext applicationContext;
2-1 private final ObjectProvider<CallServiceV2> callServiceProvider;
public void external() {
log.info("call external");
1-2 CallServiceV2 callServiceV2 = applicationContext.getBean(CallServiceV2.class);
2-2 CallServiceV2 callServiceV2 = callServiceProvider.getObject();
callServiceV2.internal(); //외부 메서드 호출
}
public void internal() {
log.info("call internal");
}
}
ApplicationContext, ObjectProvider는 객체를 스프링 컨테이너에서 조회하는 것을 스프링 빈 생성 시점이 아니라 실제 객체를 사용하는 시점으로 지연할 수 있습니다.
해결 방법 - 구조 변경
스프링에서도 해당 방법을 제일 권장합니다.
@Slf4j
@Component
@RequiredArgsConstructor
public class CallServiceV3 {
private final InternalService internalService;
public void external() {
log.info("call external");
internalService.internal(); //외부 메서드 호출
}
}
@Slf4j
@Component
public class InternalService {
public void internal() {
log.info("call internal");
}
}
'Spring' 카테고리의 다른 글
[Spring Boot + Java] JAR와 WAR 간단 정리 (1) | 2024.10.06 |
---|---|
[Spring] Spring AOP의 한계 (0) | 2024.10.04 |
[Spring] 스프링 포인트컷 지시자 정리 (0) | 2024.10.01 |
[Spring] Spring AOP 사용 방법 - @Aspect 활용 (0) | 2024.09.27 |
[Spring] 스프링 AOP 정리 (0) | 2024.09.26 |