스프링 컨테이너 ➡️ 싱글톤 레지스트리 ➡️ 스프링 빈이 싱글톤이 되도록 보장
아래 코드를 보면 memberService와 orderService를 호출하면 memberRepository가 세번 호출될 것으로 보인다. (스프링 빈에 등록할 때 1번 호출 포함)
@Bean
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService(){
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
그러나 실제로는 3번이 아닌 1번만 호출된다.
🔷 스프링은 클래스의 바이트코드를 조작하는 라이브러리를 사용하여 이를 가능케 한다.
스프링은 CGLIB라는 바이트코드 조작 라이브러리를 사용해서 AppConfig 클래스를 상속받은 임의의 다른 클래스를 생성하고, 생성한 클래스를 스프링 빈으로 등록
🔷 AppConfig@CGLIB 동작 방식
@Bean이 붙인 메서드마다 이미 스프링 빈이 존재하면 존재하는 빈을 반환
스프링 빈이 없으면 생성해서 스프링 빈으로 등록하고 반환하는 코드가 동적으로 만들어짐
➡️ 싱글톤 보장 가능
🔷 정리
@Configuration 어노테이션을 붙이면 CGLIB 기술을 사용해서 싱글톤을 보장
@Bean만 사용하면 스프링 빈으로 등록은 하지만 싱글톤 보장은 X
➡️ 스프링 설정 정보에는 @Configuration을 붙인다.
인프런 스프링 핵심 원리 - 기본편 (김영한) 참조