Dependency Injection을 이해한다.

Goal

  • Object Dependencies을 이해한다.
  • Dependency Injection의 개념과 장점을 이해한다.
  • Spring Container를 이해한다.
  • 구체적인 예시를 확인한다.

Object Dependencies(객체 의존성)

현재 객체가 다른 객체와 상호작용(참조)하고 있다면 현재 객체는 다른 객체에 의존성을 가진다.

public class PetOwner{
    private AnimalType animal;

    public PetOwner() {
        this.animal = new Dog();
    }
}

Dependency Injection(의존성 주입)

객체 자체가 아니라 Framework에 의해 객체의 의존성이 주입되는 설계 패턴

의존성 주입 방법 (세 가지)

  1. Contructor Injection
    • 생성자를 통한 전달
    • <constructor-arg ref="cat"></constructor-arg>
  2. Method(Setter) Injection
    • setter()을 통한 전달
    • <property name="myName" value="poodle"></property>
  3. Field Injection
    • 멤버 변수를 통한 전달

장점

  1. Reduced Dependencies
    • 종속성이 감소한다.
    • components의 종속성이 감소하면 변경에 민감하지 않다.
  2. More Reusable Code
    • 재사용성이 증가한다.
    • 일부 인터페이스의 다른 구현이 필요한 경우, 코드를 변경할 필요없이 해당 구현을 사용하도록 components를 구성할 수 있다.
  3. More Testable Code
    • 더 많은 테스트 코드를 만들 수 있다.
    • Mock 객체는 실제 구현의 테스트로 사용되는 객체
      • 종속성을 components에 주입할 수 있는 경우 이러한 종속성의 Mock 구현을 주입할 수 있다.
      • 예를 들어, Mock 객체가 올바른 객체를 반환할 때, null을 반환할 때, 예외가 발생할 때 모두 처리한다.
  4. More Readable Code
    • 코드를 읽기 쉬워진다.
    • components의 종속성을 보다 쉽게 파악할 수 있으므로 코드를 쉽게 읽을 수 있다.

간단한 예시

  1. AnimalType에 대한 구체적인 Class를 생성한다.
    • Dog Class, Cat Class
  2. PetOwner 객체에 AnimalType 객체를 전달한다.
    • Contructor Injection
      • 생성자를 통한 전달
      • <constructor-arg ref="cat"></constructor-arg>
    • Method(Setter) Injection
      • setter()을 통한 전달
      • <property name="myName" value="poodle"></property>
    • Field Injection
      • 멤버 변수를 통한 전달

Injection Collection


Spring Container

Spring Framework의 핵심 컴포넌트

역할

  1. 객체(bean)를 생성하고
  2. 객체들을 함께 묶고
  3. 객체들을 구성하고
  4. 객체들의 전체 수명주기(lifecycle)를 관리

설정 방법

  1. XML
    • 1) 빈 객체 정의 (Bean Definition)
    • 2) 의존성 주입 (Dependency Injection)
  2. Java Annotations
  3. Java Code

유형

  1. BeanFactory
    • 주로 단순한 DI에서만 사용한다.
    • XMLBeanFactory
  2. ApplicationContext
    • Resources가 제한되어 있지 않은 모든 곳에 사용한다.
    • ClassPathXmlApplicationContext
    • /* main함수에서 Contaier를 생성 */
      // 설정 파일은 인자로 넣고, 해당 설정 파일에 맞게 bean들을 만든다.
      ApplicationContext context = 
       new ClassPathXmlApplicationContext("spring/di/beans/bean.xml");
      // getBean()을 통해 bean의 주소값을 가져온다.  
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      

Spring Container와 DI의 예시

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

    <bean id="dog" class="spring.di.Dog">
        <property name="myName" value="poodle"></property>
    </bean>

    <bean id="cat" class="spring.di.Cat">
        <property name="myName" value="bella"></property>
    </bean>

    <bean id="petOwner" class="spring.di.PetOwner">
        <constructor-arg ref="cat"></constructor-arg>
    </bean>
</beans>

관련된 Post

References