인프런에 김영한 강사님의 스프링 강의를 들으며 예제코드를 만들던 중 오류를 만나게 되었다.
강의 중에 싱글톤패턴에 대해 배우는 구간이 있는데 이 구간에서 스프링 빈을 등록하고 스프링 컨테이너가 자동으로 싱글톤패턴을 관리해주는걸 직접 코드로 쳐보고 경험해보는 예제였다.
오류가 난 부분이다.
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
System.out.println("AppConfig.memberService");
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService() {
System.out.println("AppConfig.orderService");
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public MemberMemoryRepository memberRepository() {
System.out.println("AppConfig.memberRepository");
return new MemberMemoryRepository();
}
@Bean
public DiscountPolicy discountPolicy() {
return new RateDiscountPolicy();
}
}
이 코드는 강의 초반부분에 스프링을 적용하지 않고 순수 자바 코드로만 기능을 구현해놓은 상태에서 실행클래스가 인터페이스와 구현체를 모두 의존하고 있는 문제에서 리팩토링하며 의존성 주입을 통해 문제를 해결하기 위해 작성한 코드이다.
그런데 이 코드에 MemberMemoryRepository 메소드 부분에 static이 붙어있는게 원인이었다.
오류가 나서 로그를 읽어봐도 어디가 문제인지 감이 잡히지 않아 검색해보고 GPT를 사용해본 결과
<aside> 💡
스프링 컨테이너는 그 메서드를 호출해서 객체를 생성하는 것이 아니라, 내부적으로 ‘프록시’ 객체가 호출을 가로채서 싱글톤으로 관리한다. 였다.
</aside>
메소드에 static이 붙어있는것 때문에 클래스레벨에서 실행되어서 프록시가 객체를 가로채지 못했던 것이다.
앞으로 싱글톤패턴을 사용하려고 할땐 static을 붙이면 안된다는걸 배운 좋은 경험이었다.