hongdangmoo 2023. 7. 11. 00:41

-> 지금까지는 순수 자바 코드로 코드를 작성했다. 이제 스프링을 사용한다.

-> 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 RateDiscountPolicy();
    }
}

-> AppConfig에 @Configuration을, 각 메서드에는 @Bean을 붙인다.

 

-> MemberServiceTest에 스프링 컨테이너 적용

public class MemberServiceTest {
    MemberService memberService;

    @BeforeEach // 각 테스트 실행 전 호출되도록 하는 애너테이션
    public void beforeEach(){
//        AppConfig appConfig = new AppConfig();
//        memberService = appConfig.memberService();
        ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        memberService = ac.getBean("memberService", MemberService.class);
    }
    @Test
    @DisplayName("회원 가입 테스트")
    void join(){
        // given
        Member member = new Member(1L, "memberA", Grade.VIP);

        // when
        memberService.join(member);
        Member findMember = memberService.findMember(member.getId());

        // then
        Assertions.assertThat(member).isEqualTo(findMember);
    }
}

-> OrderServiceTest 스프링 컨테이너 적용

public class OrderServiceTest {
    MemberService memberService;
    OrderService orderService;

    @BeforeEach // 각 테스트 실행 전 호출되도록 하는 애너테이션
    public void beforeEach(){
//        AppConfig appConfig = new AppConfig();
//        memberService = appConfig.memberService();
//        orderService = appConfig.orderService();
        ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        memberService = ac.getBean("memberService", MemberService.class);
        orderService = ac.getBean("orderService", OrderService.class);
    }

    @Test
    @DisplayName("주문 및 할인 정책 테스트")
    void createOrder(){
        Long memberId = 1L;
        Member member = new Member(memberId, "memberA", Grade.VIP); // 등급인 VIP인 memberA라는 회원
        memberService.join(member); // 회원 가입

        Order order = orderService.createOrder(memberId, "itemA", 10000); // 주문 생성
        Assertions.assertThat(order.getDiscountPrice()).isEqualTo(1000); // 할인된 금액이 1000원이 맞는지 검증
    }
}

- 이 테스트들을 실행하면 기존 테스트 코드의 결과와 같은 결과가 나온다.

 

◎ 스프링 컨테이너

-> ApplicationContext를 스프링 컨테이너라 한다.

-> 기존에는 개발자가 AppConfig를 통해 직접 객체 생성하고 DI 했지만, 이제는 스프링 컨테이너를 사용한다.

-> 스프링 컨테이너는 @Configuration이 붙은 AppConfig를 구성 정보로 사용하고, @Bean이 붙은 메서드들을 모두 호출하여 반환된 객체를 스프링 컨테이너에 등록한다. 스프링 컨테이너에 등록된 것을 스프링 빈이라고 한다.

-> 스프링 빈은 @Bean이 붙은 메서드의 이름을 스프링 빈 이름으로 한다.

-> ac.getBean("스프링 빈 이름", 객체.class)메서드를 통해 스프링 빈을 찾을 수 있다. memberService = ac.getBean("memberService", MemberService.class); 이 코드는 memberService라는 이름의 스프링 빈을 찾는 것이다.

-> 이전까지는 개발자가 직접 자바 코드로 모든 의존관게를 관리했지만 스프링을 사용하면 스프링 컨테이너에 객체를 스프링 빈으로 등록하여 스프링 컨테이너에서 스프링 빈을 찾아 사용하게 된다.

 

☆ 참고

[인프런]스프링 핵심 원리 - 기본편