부모 타입으로 조회하면 자식 타입까지 함께 조회된다. 

 

 

 

모든 자바 객체의 최고부모인 'Object 타입' 으로 조회하면 모든 스프링 빈을 조회한다. 

클래스에서 눈에 안보이지만 사실 Extends Object를 하고있다.

public class A extends Obect {
}

 

 

 

 

자식 2개인 부모 DiscountPolicy를 조회해보기
public class ApplicationContextExtendsFindTest {

	AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);
	
	@Test
	@DisplayName("부모 타입으로 조회시, 자식이 둘 이상이면, 중복 오류가 발생한다.")
	void findBeanByParentTypeDuplicate() {
		DiscountPolicy bean = ac.getBean(DiscountPolicy.class); 
	}
	
	@Configuration
	static class TestConfig {
		
		@Bean
		public DiscountPolicy rateDiscountPolicy() {
			return new RateDiscountPolicy();
		}
		
		@Bean
		public DiscountPolicy fixDiscountPolicy() {
			return new FixDiscountPolicy();
		}
	}
}

 

▶ 부모인 DiscountPolicy 는 자식 RateDiscountPolicy, FixDiscountPolicy 둘 다 조회가 되어 중복오류가 난다. 

 

 

NoUniqueBeanDefinitionException

 

 

 

 

NoUniqueBeanDefinitionException 예외처리 하기 >  assertThrows 

@Test
	@DisplayName("부모 타입으로 조회시, 자식이 둘 이상이면, 중복 오류가 발생한다.")
	void findBeanByParentTypeDuplicate() {
		assertThrows(NoUniqueBeanDefinitionException.class, 
				() -> ac.getBean(DiscountPolicy.class));
	}

 

 

 

빈 이름을 지정해주기
public class ApplicationContextExtendsFindTest {

	AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);
	
	@Test
	@DisplayName("부모 타입으로 조회시, 자식이 둘 이상이면, 빈 이름을 지정하면 된다.")
	void findBeanByParentTypeBeanName() {
		DiscountPolicy rateDiscountPolicy = ac.getBean("rateDiscountPolicy" ,DiscountPolicy.class);
		Assertions.assertThat(rateDiscountPolicy).isInstanceOf(RateDiscountPolicy.class); 
	}
	
	@Configuration
	static class TestConfig {
		
		@Bean
		public DiscountPolicy rateDiscountPolicy() {  // 이걸로 지정
			return new RateDiscountPolicy();
		}
		
		@Bean
		public DiscountPolicy fixDiscountPolicy() {
			return new FixDiscountPolicy();
		}
	}
}

 

@Test
@DisplayName("부모 타입으로 조회시, 자식이 둘 이상이면, 빈 이름을 지정하면 된다.")
void findBeanByParentTypeBeanName() {
         DiscountPolicy rateDiscountPolicy = ac.getBean("rateDiscountPolicy" ,DiscountPolicy.class);

 

 

 

특정 하위 타입으로 조회해보기

 

@Test
@DisplayName("특정 하위 타입으로 조히")
void findBeanBySubType() {
    RateDiscountPolicy bean = ac.getBean(RateDiscountPolicy.class);
    Assertions.assertThat(bean).isInstanceOf(RateDiscountPolicy.class); 
}

 

RateDiscountPolicy 하나밖에 없으니까 에러 안난다.

 

 

 

 


 

여기서 궁금증!

 

아래처럼 반환값을 구현체로 해도 되지않을까? 

@Configuration
static class TestConfig {

    //@Bean
    //public DiscountPolicy rateDiscountPolicy() {  
    //    return new RateDiscountPolicy();
    //}
    
    //@Bean
    //public DiscountPolicy fixDiscountPolicy() {
    //   return new FixDiscountPolicy();
    //}
    
    // 반환값을 구현체로?
    @Bean
    public RateDiscountPolicy rateDiscountPolicy() { 
        return new RateDiscountPolicy();
    }

    @Bean
    public FixDiscountPolicy fixDiscountPolicy() {
        return new FixDiscountPolicy();
    }
}

 

▶ 구체적인걸로 해도되지만! 역할과 구현을 나눈 것 처럼 인터페이스(역할)로 해두는게 다형성에도 좋고 가독성에도 좋다!

 

 

반응형
LIST

+ Recent posts