• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

@EnableAsync 에서의 default 가 JDK 동적 프록시인 이유

23.09.03 21:45 작성 23.09.03 21:47 수정 조회수 484

0

안녕하세요 김영한님!
강의 감사히 잘 들었습니다!!
완강을 한지는 몇개월이 지났는데, 코딩 중 궁금한 점이 생겨 글을 작성합니다!

제목에서와 같이 @EnableAsync 라는 어노테이션을 코드에서 발견했는데요.
해당 어노테이션의 속성에는 proxyTargetClass 라는 속성을 넣을 수 있게 되어 있었습니다.

하지만 저는 그 속성을 보자마자 당황스러웠는데요. 보통 스프링 부트는 default로 CGLIB를 사용해서 proxyTargetClass = true 라는 속성이 있으면 회색빛으로 "이 속성을 안써도 괜찮다" 라는 언급을 해줍니다. 그런데 제가 proxyTargetClass = true를 보았을땐 명확한 하얀색으로 되어있어 이제까지 잘못알고 있었나하여 굉장히 당황했습니다.

당황함을 뒤로한채 해당 어노테이션의 설명을 보니, 이 어노테이션에서는 proxyTargetClass의 default = false로 되어있고, CGLIB를 사용하고 싶다면 true로 바꾸라는 설명이 쓰여있었습니다.

왜 비동기를 설정하는 어노테이션에서 이런 속성을 정의해야하는것일까요..


+ 추가질문) 이 어노테이션의 속성을 보면서 느낀점은 한 프로젝트 내에서 A는 CGLIB로 B는 JDK 동적 프록시로 사용하고 싶다면 B를 빈후처리기를 사용해서 직접 설정해주면 될까요?

답변 1

답변을 작성해보세요.

1

안녕하세요. 차형석님

우선 @EnableAsync는 @Async 애노테이션을 사용해서 특정 메서드를 비동기로 실행할 때 필요합니다.

(이 부분은 검색해보시면 많은 실행 예시를 보실 수 있을거에요.)

그런데 메서드가 비동기로 실행되려면 중간에 별도의 쓰레드에서 실행하는 코드를 넣어야 합니다.

스프링은 이 경우 프록시를 사용해서 별도의 쓰레드에서 해당 메서드를 실행하도록 합니다.

따라서 여기에는 프록시 기술이 사용됩니다.

프록시를 생성하는 방법은 JDK 동적 프록시나 CGLIB를 사용할 수 있습니다.

최근 스프링 부트를 사용하면 AOP 적용시 기본으로 CGLIB를 사용합니다.

하지만 @EnableAsync는 스프링 부트의 방식과는 무관하게 JDK 동적 프록시나 CGLIB를 선택할 수 있습니다.

그 이유는 아마도 @EnableAsync 자체가 스프링 부트와 무관하게 오래전부터 스프링 프레임워크에서 자체적으로 제공하는 기술이기 때문에 그런 것 같습니다.

추가 질문

@EnableAsync의 proxyTargetClass 속성은 전역 설정입니다. 즉, 프로젝트 전체에 적용됩니다. 따라서, @EnableAsync 설정으로는 A와 B에 대해 각각 다른 프록시 생성 방식을 지정할 수 없습니다. 별도의 방식으로 해결하려면 직접 프록시 생성 코드를 사용해서 프록시를 프로그래밍 방식으로 생성해야 합니다.

감사합니다.

차형석님의 프로필

차형석

질문자

2023.09.06

자세한 답변 감사합니다!