xml 파일을 이용해 Bean 을 등록하고 사용하기 위해 GenericXmlApplicationContext 클래스를 사용합니다. GenericXmlApplicationContext 에 Bean 설정을 정의한 appConfig.xml 파일을 인자로 넘겨주면 스프링 컨테이너를 생성한 후 xml 파일에 정의된 객체들을 스프링 Bean 으로 등록해줍니다.
ApplicationContext 객체내 getBean 을 사용하면 스프링 컨테이너에 저장된 Bean 객체를 가져와 사용할 수 있습니다.
Configuration 어노테이션을 통해 AppConfig를 설정(구성) 정보로 사용한다. Bean 어노테이션을 통해 스프링 컨테이너에 등록한다.
@Configuration publicclassAppConfig {
@Bean public MemberService memberService(){ returnnewMemberServiceImpl(memberRepository()); }
@Bean public MemberRepository memberRepository() { returnnewMemoryMemberRepository(); }
@Bean public OrderService orderService(){ returnnewOrderServiceImpl(memberRepository(), discountPolicy()); }
@Bean public DiscountPolicy discountPolicy() { // return new FixDiscountPolicy(); returnnewRateDiscountPolicy(); } }
@Configuration 과 @Bean 를 사용해 정의한 Bean 객체를 등록 및 사용하기 위해 AnnotationConfigApplicationContext 클래스를 사용합니다. AnnotationConfigApplicationContext 에 Bean 설정을 정의한 AppConfig.class 를 넘겨주면 스프링 컨테이너를 생성한 후 @Bean 이 붙은 메소드를 호출해 반환받은 객체들을 스프링 Bean 으로 등록합니다.
@Test @DisplayName("구체 타입으로 조회") voidfindBeanByType2(){ MemberServiceImplmemberService= ac.getBean("memberService", MemberServiceImpl.class); // 구체적으로 적는 것은 별로 않좋다. // 될 수 있는한 추상화한 인터페이스에 테스트를 맞춘다. assertThat(memberService).isInstanceOf(MemberServiceImpl.class); }
@Test @DisplayName("타입으로 조회시 같은 타입이 둘 이상 있으면, 중복 오류가 발생한다.") voidfindBeanByTypeDuplicate(){ assertThatThrownBy(() ->{ ac.getBean(MemberRepository.class); }).isInstanceOf(NoUniqueBeanDefinitionException.class); }
@Test @DisplayName("타입으로 조회시 같은 타입이 둘 이상 있으면, 빈 이름을 지정하면 된다.") voidfindBeanByName(){ MemberRepositorymemberRepository= ac.getBean("memberRepository1", MemberRepository.class); assertThat(memberRepository).isEqualTo(MemberRepository.class); }
@Test @DisplayName("부모 타입으로 조회시, 자식이 둘 이상 있으면, 중복 오류가 발생한다.") voidfindBeanByParentTypeDuplicate(){ assertThatThrownBy(() -> { ac.getBean(DiscountPolicy.class); }).isInstanceOf(NoUniqueBeanDefinitionException.class); }
@Test @DisplayName("부모 타입으로 조회시, 자식이 둘 이상 있으면, 빈 이름을 지정한다.") voidfindBeanByParentTypeBeanName(){ DiscountPolicyrateDiscountPolicy= ac.getBean("rateDiscountPolicy", DiscountPolicy.class); assertThat(rateDiscountPolicy).isInstanceOf(RateDiscountPolicy.class);
}
@Test @DisplayName("특정 하위 타입으로 조회") voidfindBeanBySubType(){ // 구체적인 타입을 지정 RateDiscountPolicybean= ac.getBean(RateDiscountPolicy.class); assertThat(bean).isInstanceOf(RateDiscountPolicy.class); }