염몽 개발일지
Published 2024. 9. 7. 14:48
Spring. @Configuration Study/Spring

@Configuration

 

먼저 각각의 빈들은 @Configuration이 있든 없든 싱글톤으로 유지된다.

 

@Configuration 어노테이션을 사용하지 않고
@Bean으로만 사용한다면, 스프링 컨테이너에는 등록이 되지만
SpringCGLIB 클래스가 자식으로 등록이 되지 않아 대부분의 싱글톤 기능을 모두 잃게 된다. 무슨 의미일까? 아래를 참고해보자.

@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() {
        //return new FixDiscountPolicy();
        return new RateDiscountPolicy();
    }
}
    @Test
    void configurationTest() {
        ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        MemberServiceImpl memberService = ac.getBean("memberService", MemberServiceImpl.class);
        OrderServiceImpl orderService = ac.getBean("orderService", OrderServiceImpl.class);
        MemberRepository memberRepository = ac.getBean("memberRepository", MemberRepository.class);

        MemberRepository memberRepository1 = memberService.getMemberRepository();
        MemberRepository memberRepository2 = orderService.getMemberRepository();

        System.out.println("memberRepository1 = " + memberRepository1);
        System.out.println("memberRepository2 = " + memberRepository2);
        System.out.println("memberRepository = " + memberRepository);

        assertThat(memberRepository1).isSameAs(memberRepository2).isSameAs(memberRepository);

    }
call AppConfig.memberService  
call AppConfig.memberRepository  
call AppConfig.orderService  
memberRepository1 = hello.core.member.MemoryMemberRepository@47da3952  
memberRepository2 = hello.core.member.MemoryMemberRepository@47da3952  
memberRepository = hello.core.member.MemoryMemberRepository@47da3952

 

 

memberService(),orderService()와 같이 내부에memberRepository()가 여러 곳에서 호출되어

new MemoryMemberRepository() 가 호출되어 여러개의 객체가 생성될 때

@Configuration이 없다면 서로 다른 여러개의 객체가 생성된다.

 

하지만 @Configuration 애노테이션이 있다면 memberRepository()와 같은 메서드 호출을 중간에 가로챌 수 있다.
해당 코드가 바로 호출 되는 것이 아니라 스프링 컨테이너에 이미 인스턴스가 생성되어있다면

컨테이너를 이용하여 스프링 빈을 찾아오게 된다.

 

결과적으로 MemoryMemberRepository 객체는 딱 1개만 생성되어 사용된다.

  • @Configuration 를 사용하지 않는다면 스프링 컨테이너에서 관리하지 않는다.
    • memberRepository() 처럼 의존관계 주입이 필요해서 메서드를 직접 호출 할 때 싱글톤을 보장하지 않는다.
  • 스프링 설정 정보는 항상 @Configuration을 사용하면 된다.

'Study > Spring' 카테고리의 다른 글

Spring. 스코프와 프록시  (1) 2024.09.08
Spring. ObjectProvider  (0) 2024.09.08
Spring. 입문  (0) 2024.08.16
profile

염몽 개발일지

@염몽이

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!