스프링 기본원리(3)

1 minute read

앞서 설명한 AppConfig를 활용한 스프링으로 전환

AppConfig 수정

@Configuration
public class AppConfig {
    @Bean
    public MemberService memberService(){
        return new MemberServiceImpl(memberRepository());
    }
    @Bean
    public MemoryMemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
    @Bean
    public OrderService orderService(){
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }
    @Bean
    public DiscountPolicy discountPolicy() {
        return new RateDicountPolicy();
    }
}
  • 스프링 컨테이너는 @Configuration 이 붙은 AppConfig 를 설정(구성) 정보로 사용한다. 여기서 @Bean 이라 적힌 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록한다. 이렇게 스프링 컨테이너에 등록된 객체를 스프링 빈이라 한다.
  • 빈 이름은 메서드 이름이며 항상 다른 이름을 사용하여야 한다.
  • 직접 부여하려면 @Bean(name=”원하는이름”)을 사용

스프링 컨테이너 적용하여 사용해보기

적용 전은 AppConfig를 직접 선언하여 할인정책 객체를 불러왔다.

AppConfig appConfig = new AppConfig();
MemberService orderService = appConfig.memberService();

변경 후

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = applicationContext.getBean("memberService",MemberService.class);
Member member = new Member(1L,"Changmin", Grade.VIP);
memberService.join(member);
  • ApplicationContext를 스프링 컨테이너라고 한다.
  • 이전에는 개발자가 필요한 객체를 AppConfig 를 사용해서 직접 조회했지만, 이제부터는 스프링 컨테이너를 통해서 필요한 스프링 빈(객체)를 찾아야 한다.
  • 스프링 빈은 applicationContext.getBean() 메서드를 사용해서 찾을 수 있다.
  • getBean(“메소드이름”,메소드클래스)로 호출한다.

스프링 빈 조회하기

  • 모든 빈 조회
    @Test
    @DisplayName("모든Bean출력하기")
    void findAllBean(){
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            Object bean = ac.getBean(beanDefinitionName);
            System.out.print("name="+beanDefinitionName+"object="+bean);
        }
    }
  • 빈 이름으로 조회
    void findBeanByName(){
        MemberService memberService = ac.getBean("memberService",MemberService.class);
    }
  • 이름없이 타입으로만 조회
    void findBeanByName(){
        MemberService memberService = ac.getBean(MemberService.class);
    }

-> 동일한 타입을 가지는 빈이 있다면 이름을 지정해줘서 조회하기

  • 동일한 타입을 모두 조회하기
    void findAllTypeBean(){
        Map<String, MemberRepository> beansOfType = ac.getBeansOfType(MemberRepository.class);

스프링 빈 조회 - 상속관계

  • 부모 타입으로 조회하면, 자식 타입도 함께 조회한다.

GitHub Logo

아래와 같이 동일한 부모를 가지는 빈이 있다고 가정하자

    @Configuration
    static class TestConfig{
        @Bean
        public DiscountPolicy rateDiscountPolicy(){
            return new RateDicountPolicy();
        }
        @Bean
        public DiscountPolicy fixDiscountPolicy(){
            return  new FixDicsountPolicy();
        }
    }

-> 아래 코드로 테스트

    @Test
    void findBeanByParent(){
        assertThrows(NoUniqueBeanDefinitionException.class,
                ()-> ac.getBean(DiscountPolicy.class));
    }

-> DiscountPolicy의 자식들을 모두 호출하기 때문에 NoUniqueBeanDefinitionException에러가 발생한다. 그래서 자식들은 이름으로 호출하여야 한다.

출처 : 인프런 김영한의 스프링 핵심원리 기본편

Leave a comment