본문 바로가기
프로그래밍/Spring

[Spring] Spring의 IoC/DI Container

by 사바라다 2020. 3. 21.

 

안녕하세요. 저번 포스팅에서 IoC와 DI의 개념에 대해서 알아보았습니다. IoC 개념을 설명하며 Spring의 IoC는 일반적인 IoC 개념에 DI를 의 개념을 추가한 IoC/DI Container라고 설명을 드렸습니다. 오늘은 구체적으로 일반적인 IoC에 어떤 개념이 추가 된것인지 한번 보도록 하겠습니다.

본편에 들어가기 전에 먼저 Spring에 대한 용어를 정리한 후 Spring Container의 구조에 대해서 알아보도록 하겠습니다.

용어 정리

Spring IoC를 공부하다보면 생소하지만 한번쯤은 흘려 들어본 용어들이 많이 나옵니다. 이러한 용어를 정리하는 시간을 가지도록 하겠습니다.

  • 빈(Bean)
    • 빈 또는 빈 오브젝트는 Spring이 IoC 방식으로 관리하는 오브젝트라는 뜻. 즉, 우리가 일반적으로 사용해왔던 new를 이용한 오브젝트 생성 방법이라던지는 포함되지 않습니다. Bean은 Container가 생성하며 관리하는 오브젝트라는 뜻입니다.
  • 빈 팩토리(Bean Factory)
    • Spring의 IoC를 담당하는 핵심 컨테이너입니다. 빈을 등록하고, 생성하고, 조회하고 돌려주고, 그 외에 부가적인 Bean을 관리하는 기능을 담당한다. 일반적으로 빈 팩토리를 바로 사용하기 보다는 이를 확장한 어플리케이션 컨텍스트를 이용한다.
  • 어플리케이션 컨텍스트(Application Context)
    • 빈 팩토리를를 확장한 IoC 컨테이너입니다. 빈 팩토리의 기능에 부가적인 서비스를 추가로 제공하고 있습니다. ApplicationConext Class는 BeanFactory Class를 상속받아 구현되어있습니다.

Spring IoC Container 사용

public class Factory {
    public static A a() {
        return new A();
    }

    public static B b_1() {
        return new B_1();
    }

    public static B b_2() {
        return new B_1();
    }
}

우리가 IoC개념을 쉽게 적용시키기 위한 방법은 위와 같이 Factory Class를 생성하여 사용하는 것입니다. 이렇게 Class를 구성하여 사용하고자 하는 Client Class에서 Factory.a() d 이런식으로 사용할 수 있게 됩니다.

 /*
  * Bean Factory가 사용할 설정정보라는 표시 
  * (Component Scan을 통해 Bean으로 생성)
  */
@Configuration
public class Factory {

    @Bean // 생성되어질 Bean이라는 표시
    public A a() {
        return new A();
    }

    @Bean(name="b_1")
    public B b_1() {
        return new B_1();
    }

    @Bean(name="b_2")
    public B b_2() {
        return new B_2();
    }
}

위는 Spring의 Bean Factory를 이용하여 작성한 IoC 방법입니다. 구성은 크게 다르지 않습니다. 직접 만든 Factory Class가 존재하며 각 @Bean Annotation이 붙은 메서드 들은 각각 return 되어지는 오브젝트를 bean으로 생성한다는 의미입니다. 그리고 클라이언트에서는 context.getBean("a", A.class)의 형태로 객체를 얻어내어 사용할 수 있습니다.

Spring Container 구조

Spring에서 Bean의 생성과 관계설정과 같은 제어를 담당하는 IoC 오브젝트를 bean factory라고 부릅니다. 그리고 이런 bean factory는 Spring Container인 Application Context안에 있습니다.

아래는 bean의 생성부터 사용까지의 다이어그램을 나태낸 것입니다.

Bean Factory 사용 flow

flow를 간단히 보도록 하겠습니다.

  1. Factory와 a, b_1의 bean을 ApplicationContext(이하 빈팩토리)에 등록합니다.
    1. 등록이 실제 오브젝트의 생성을 의미하진 않습니다.
  2. Client에서 해당 bean을 사용하려고 요청합니다.
  3. 빈 팩토리는 해당 빈이 있는지 조회합니다.
    1. 빈 목록에 있다면 오브젝트 확인으로 넘어갑니다.
    2. 빈 목록에 없다면 Exception을 발생시킵니다.
  4. 오브젝트 확인 (bean 스코프가 singleton일 경우)
    1. 만약 해당 빈이 아직 한번도 사용되지 않아 생성되어 있지 않다면 해당 빈을 생성합니다.
    2. 이미 사용되어진 빈이라면 오브젝트가 만들어져 있을 것으로 바로 사용합니다. 
  5. 해당 빈을 Client에게 반환합니다.

이런 flow를 거쳐 Client는 해당 Bean을 사용할 수 있게 되는 것입니다.

Bean Factory의 장점

오히려 Annotation에 의해서 복잡하며 돌아가는 방식도 이해하기가 난해합니다. 이런 Bean Factory의 IoC Container를 사용해서 얻을 수 있는 장점이 뭘까요 ? 대표적인 장점은 아래와 같습니다.

  • Factory Class가 아무리 많아져도 Factory Class가 어떤건지 존재를 모른채 bean의 이름만으로 오브젝트를 가져올 수 있습니다.
  • 어플리케이션 컨텍스트의 역할은 단지 오브젝트의 생성과 관계설정만이 아닙니다. 해당 빈을 Singleton으로 만들지, Property로 만들지 등 만들어지는 방식, 시점과 전략을 다르게 가져갈 수 있으며 부가적으로 자동생성과 후처리, 조합등 오브젝트를 효과적으로 사용할 수 있는 다양한 방법을 제공합니다.
  • 어플리케이션 컨텍스트에 bean을 가져오는 방법을 getBean으로 명시하는것만이 아니라 contructor나 field, setter 주입등을 제공해주고 있습니다.

마무리

오늘은 이렇게해서 Spring의 IoC Container인 ApplicationContext, 그 안의 BeanFactory에 대해서 알아보았습니다.

도움이 되셨다면 아래의 광고한번 꾸욱 부탁드립니다 :)

감사합니다.

참조

토비의 스프링 3.1

댓글