인프런 커뮤니티 질문&답변

wodnrtkfka님의 프로필 이미지

작성한 질문수

스프링 핵심 원리 - 기본편

관심사의 분리

DIP구현 중, AOP과의 이슈가 발생하여 질문 드립니다

작성

·

263

·

수정됨

0

안녕하세요! 알려주신 내용을 바탕으로 제 개인프로젝트에 적용해서 리팩토링을 해보고있는데요!

DIP를 위배하지않기위해

@Getter
@Configuration
public class IamportConfig {

@Value("${secret.sec.key}")

private String secretKey ;

@Value("${api.api.key}")

private String apiKey ;

@Bean public IamportClient iamportClient()

{ return new IamportClient(apiKey, secretKey); } }

이런식으로 IamportConfig를 선언해서 주입을 해주었고

실제 코드에는

private final PurchaseService purchaseService;

private final ItemService itemService;

private final IamportClient iamportClient;

private final RedissonClient redissonClient;

private final JwtUtil jwtUtil;

private final IamportConfig iamportConfig;

이렇게 선언했습니다!

이후

@PostMapping("/api/payment/cancel")
private boolean cancelPayment(@RequestBody RefundRequestDto refundRequestDto) throws JsonProcessingException {
    RestTemplate restTemplate = new RestTemplate();


    String url = "https://api.iamport.kr/payments/cancel";

    // 요청 파라미터 설정
    MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
    formData.add("impUid", refundRequestDto.imp_uid());
    formData.add("checksum", String.valueOf(refundRequestDto.checksum()));
    formData.add("reason", refundRequestDto.reason());


    // 요청 헤더 설정
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    String token = getAccessToken(new PaymentRequestDto.getToken(iamportConfig.getApiKey(), iamportConfig.getSecretKey()));
    headers.set("Authorization", "Bearer " + token);

    // 요청 객체 생성
    HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);

    // 요청 보내기
    ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);

    // 응답 처리
    if (response.getStatusCode() == HttpStatus.OK) {
        // 각 아이템에 대해 수량 롤백 진행
        purchaseService.rollbackItemsQuantity(refundRequestDto.imp_uid());
        // 주문 상태 변경
        purchaseService.ChangeStatusToCancelled(refundRequestDto.imp_uid());
        return true;
    } else {
        return false;
    }
}


이런 코드를 사용하는과정에서
String token = getAccessToken(new PaymentRequestDto.getToken(iamportConfig.getApiKey(), iamportConfig.getSecretKey()));

이부분의 iamportConfig 가 null로 나오는 문제가 발생했습니다.

다방면으로 답을 찾아보다가 AOP를 전부 주석처리하니까 해결되더라구요. 그래서 AOP의 적용범위에서 해당 컨트롤러를 제외시켰는데 해결이 되었습니다.

이를통해 좀 알아보니까

AOP가 실행되는 시점은 새로운 PaymentRequestDto 인스턴스가 생성되기 전 이므로
AOP 프록시 객체가 cancelPayment를 감쌀때 PaymentRequestDto는 null이게 된다.
(AOP 로직이 @Value로 주입된 프로퍼티 값에 접근하기 전에 실행되어 값을 정상적으로 참조할 수 없는 상황이 발생)

라는 결론에 다다르게 되었는데,
제가 잘 이해한게 맞을까요?...!

답변 1

1

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. wodnrtkfka님

죄송하지만 질문 안내에서 말씀드린 것처럼 강의 학습에 관련된 질문을 올려주시길 부탁드립니다.

저도 마음으로는 도움을 드리고 싶지만, 하루에도 수많은 분들이 질문을 올려주십니다. 그래서 강의 학습과 관련된 질문에 초점을 맞추는 것이 맞다 생각합니다. 다시한번 이해를 부탁드립니다.

wodnrtkfka님의 프로필 이미지
wodnrtkfka
질문자

아, 그 영한님 강의에서 나온 AOP와 본 강의에서의 DIP를 적용하는과정에서

AOP가 새로운 객체가 만들어지는시점전에 프록시로 감싸버려서 발생하는원인같아서,,

AOP 로직이 @Value로 주입된 프로퍼티 값에 접근하기 전에 실행되어 값을 정상적으로 참조할 수 없는 상황이 발생하는게 맞는건지가 궁금했고 자세한 코드를 첨부했던건데 강의와는 관계없는내용일까요?

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. wodnrtkfka님

죄송하지만 개인 프로젝트에서 발생한 이슈를 이곳에서 도움을 드리기는 어렵습니다.

저도 서포터즈 분들도 하루에 수 많은 분들의 질문에 답변을 드려야해서, 강의 학습 내용과 관련된 질문에 초점을 맞추고 있습니다. 이해를 부탁드려요.

감사합니다.

wodnrtkfka님의 프로필 이미지
wodnrtkfka
질문자

앗 네! 답변주셔서 감사합니다.

강의내용을 개인프로젝트에 적용하면서 공부해보고있었는데
적용과정에서 생긴 의문이어서 질문해도되는줄 알았습니다 ㅜㅜ 죄송합니다!

다음부터는 강의내용을 100%기반으로 질문토록 하겠습니다

감사합니다 :)