@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public static MemoryMemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public DiscountPolicy discountPolicy() {
return new RateDiscountPolicy();
}
}
위 코드를 한번 살펴보자.
@Bean memberService를 호출하면 new MemoryMemberRepository();를 호출한다.
또 @Bean orderSerivce를 호출하면 new MemoryMemberRepository();를 호출한다.
어!! 그러면 MemoryMemberRepository()가 2번 호출이 되서 싱글톤이 깨지게 되는거 아닌가?
하지만 스프링빈 컨테이너에서 이것을 싱글톤이 되도록 관리해준다.
실제로 test코드로 memberService.getrepository()와 orderSerivce.getrepository()를 만들어서 비교해보아도 같은 값이 나오는 것을 확인할 수 있다.
심지어 이 둘은 memberRepository와 같다!!!
어떻게 이렇게 되는 것일까??
@Configuration이 붙은 AppConfig를 출력해서 알아보자.
순수한 자바코드라면
class hello.core.AppConfig
이렇게 출력이 예상되지만, 의외로 출력해보면 'xxxxCGLIB'의 형식이 붙어서 출력되는 것을 확인할 수 있다.
-> 즉 이건 내가 만든 코드가 아니라, Spring이 @Bean을 등록하는 과정에서 바이트코드를 조작하는 CGLIB라이브러리를 사용하여 AppConfig를 상속받은 임의의 클래스를 Bean으로 등록한 것이 출력된 것이다.
만약 @Configuration코드를 뺀다면 ?
빈으로는 등록되지만 싱글톤이 깨진다!