Spring의 싱글톤 컨테이너

hoyong.eom·2023년 6월 29일
0

스프링

목록 보기
1/59
post-thumbnail

Spring

싱글톤 컨테이너

스프링에서는 보통 아래와 같이 스프링 빈을 등록할 수 있다.

// 김영한님 강의에서 나온 예시 코드입니다.
@Configuration
public class AppConfig {
    
    @Bean
    public MemberService memberService(){
        System.out.println("call AppConfig.memberService");
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository(){
        System.out.println("call AppConfig.memberRepository");
        return new MemoryMemberRepository();
    }

    @Bean
    public OrderService orderService(){
        System.out.println("call AppConfig.orderService");
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }

    @Bean
    public DiscountPolicy discountPolicy(){
        System.out.println("call AppConfig.discountPolicy");
        return new RateDiscountPolicy();
    }
}

그런데 스프링에서는 정말 편리하게도 위 스프링 빈을 싱글톤 객체로서 스프링 컨테이너에서 관리된다고 한다.
즉, 여러 클라이언트에서 몇번의 스프링 빈을 조회해도 모두 같은 스프링 빈을 전달 받는다는 의미가 된다.
그런데 위 코드만 보면 memberRepository는 3번 호출되어서 싱글톤 객체로 유지가 불가능할것같다.
하지만! 실제로는 스프링이 싱글톤이 되도록 유지해준다고 한다!!

그 비밀은?

그 비밀은 바로 @Configuration 어노테이션에 있다고 한다!

즉, @Configuration 어노테이션이 붙은 AppConfig 클래스를 스프링 설정 파일로 등록하도록 사용한다.

ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

그러면 실제로는 AppConfig가 아니라 AppConfig를 상속받은 프록시 객체가 스프링 빈에 등록된다고 한다.
따라서, 실제 순수한 자바 객체가 아니라 CGLIB 라이브러리를 이용해서 바이트코드를 조작한 새로운 객체(프록시 객체)가 스프링 빈에 등록되어 싱글톤을 보장하도록 해주는것이라고 한다!!

여기서 중요한점은 @Configuration 어노테이션이다.

@Configuration 어노테이션이 존재해야만 싱글톤을 유지하도록 스프링 빈을 스프링 컨테이너에 등록하도록 유지한다.
만약 @Configuration 어노테이션이 없다고 스프링 빈의 싱글톤 객체로서 관리하지 않게 된다.!!

더 중요한점은 위 코드에서 memberRepository()에 의한 호출은 스프링 빈으로 관리되지 않는다. 왜그럴까?
당연하다.. 스프링으로 관리되지 않는 순수한 자바 코드이기 떄문이다.

결론

  1. @Bean만 사용해도 스프링 빈으로 등록되지만, 싱글톤을 보장하진 않는다. AppConfig 코드의 memberRepository() 처럼 의존 관계 주입이 필요한 경우 메서드를 직접 호출하면 스프링 빈으로 관리되지 않는다.
  2. @Configuration을 항상 사용하자!

참고

해당 포스팅은 아래의 강의를 공부 후 개인적으로 정리한 내용입니다.
김영한님의 스프링 기본편

0개의 댓글