AppConfig 코드
@Configuration
public class AppConfig {
@Bean
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public OrderService orderService(){
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public DiscountPolicy discountPolicy(){
// return new FixDiscountPolicy();
return new RateDiscountPolicy();
}
}
코드를 보았을 때 각각의 Bean이 호출 될 때마다 new 하여 객체를 반환하는 코드가 작성 되어있다
이 코드대로 실행될 경우 싱글톤이 보장되지 않는다.
이를 해결 하는것이 @Configuration 어노테이션이다.
@Configuration과 바이트코드 조작의 마법
스프링 컨테이너는 싱글톤 레지스트리다. 따라서 스프링 빈이 싱글톤이 되도록 보장해주어야 한다.
그런데 스프링이 자바 코드까지 어떻게 하기는 어렵다. 저 자바 코드를 보면 분명 3번 호출되어야 하는 것이 맞다.(new 할 때마다 생성된다는 가정하에)
그래서 스프링은 클래스의 바이트코드를 조작하는 라이브러리를 사용한다.
모든 비밀은 @Configuration 을 적용한 AppConfig 에 있다.
스프링이 CGLIB라는 바이트코드 조작 라이브러리를 사용해서 AppConfig
클래스를 상속받은 임의의 다른 클래스를 만들고, 그 다른 클래스를 스프링 빈으로 등록한 것이다!
@Bean이 붙은 메서드마다 이미 스프링 빈이 존재하면 존재하는 빈을 반환하고, 스프링 빈이 없으면
생성해서 스프링 빈으로 등록하고 반환하는 코드가 동적으로 만들어진다.
덕분에 싱글톤이 보장되는 것이다.
@Configuration 어노테이션을 붙이지 않으면 AppConfig를 상속받은 AppConfig@CGLIB 클레스를 생성하지 않게 되고 내부 로직이 돌지 않아 Bean이 호출될 때 마다 new 되어 싱글톤이 깨지게 된다.
'프로그래밍 > Spring' 카테고리의 다른 글
Filter (0) | 2022.06.11 |
---|---|
컴포넌트 스캔과 의존관계 주입 (@ComponentScan, @Autowired) (0) | 2022.06.10 |
싱글톤 (1) | 2022.06.10 |
appConfig (java/xml) (0) | 2022.06.10 |
스프링 빈 조회 - 상속관계 (0) | 2022.06.10 |