쌓고 쌓다

스프링 컨테이너, 스프링 빈 조회 본문

프로그래밍/spring

스프링 컨테이너, 스프링 빈 조회

승민아 2023. 7. 8. 17:42

스프링으로 전환

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는 순수 자바 코드로 DI를 했다. 스프링으로 전환하기 위해

AppConfig에서 설정을 구성한다는 @Configuration 어노테이션과

각 메서드에 @Bean을 붙여줌으로써 스프링 컨테이너에 스프링 빈으로 등록한다.

 

 

스프링 컨테이너 적용

MemberService

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = applicationContext.getBean("memberService", MemberService.class);

ApplicationContext를 '스프링 컨테이너'라고 한다.

스프링 컨테이너는 AppConfig를 설정(구성) 정보로 사용한다.

@Bean이 사용된 메소드를 모두 호출하여 반환된 객체를 스프링 컨테이너에 등록한다.

이때 등록된 객체를 '스프링 빈'이라고 한다.

스프링 빈은 @Bean이 붙은 메소드의 명을 스프링 빈의 이름으로 사용한다.

 

스프링 컨테이너 생성

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

ApplicationContext는 인터페이스다.

AnnotationConfigApplicationContext는 위의 인터페이스의 구현체이다.

스프링 컨테이너를 생성할땐 구성 정보를 지정해줘야한다. AppConfig.class로 구성 정보를 지정했다.

위의 코드는 스프링 컨테이너를 어노테이션 기반의 자바 설정 클래스로 만든 것이다. XML 기반으로도 만든다고 한다.

 

스프링 컨테이너는 구성(설정) 정보로 스프링 빈을 등록하고, 의존관계를 주입한다. 아래의 상태를 이룬다.

출처: 인프런 - 김영한
출처: 인프런 - 김영한

 

스프링 빈 조회

기본 조회 방법으로 2가지가 있다.

  1. ac.getBean(빈 이름, 타입)
  2. ac.getBean(타입)

 

이름, 타입, 구현체 타입으로 조회 코드

public class ApplicationContextBasicFindTest {

    ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

    @Test
    @DisplayName("빈 이름으로 조회")
    public void findBeanByName() {
        MemberService memberService = ac.getBean("memberService", MemberService.class);
        Assertions.assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
    }

    @Test
    @DisplayName("이름 없이 타입으로 조회")
    public void findBeanByType() {
        MemberService memberService = ac.getBean(MemberService.class);
        Assertions.assertThat(memberService).isInstanceOf(MemberService.class);
    }

    @Test
    @DisplayName("구현체 타입으로 조회")
    public void findBeanByImpl() {
        MemberService memberService = ac.getBean("memberService", MemberServiceImpl.class);
        Assertions.assertThat(memberService).isInstanceOf(MemberServiceImpl.class);
    }

    @Test
    @DisplayName("틀린 빈 이름으로 조회")
    public void findBeanByNameX() {
        // ac.getBean("WrongName", MemberService.class);
        org.junit.jupiter.api.Assertions.assertThrows(NoSuchBeanDefinitionException.class, () -> ac.getBean("WrongName", MemberService.class));
    }


}

 

 

 

 

 

 

 

Comments