DI의 개념

각 클래스간의 의존관계를 빈 설정(Bean Definition) 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것을 말한다.

  • 개발자들은 빈 설정파일(XML, annotation)에서 의존관계가 필요하다는 정보를 추가하면 된다.
  • 객체 레퍼런스를 컨테이너로부터 주입 받아서, 실행 시에 동적으로 의존관계가 생성된다.
  • 컨테이너가 흐름의 주체가 되어 애플리케이션 코드에 의존관계를 주입해주는 것이다.

DI의 장점

  • 코드가 단순해진다.
  • 컴포넌트간의 결합도가 제거된다.

DI의 유형

  1. Setter Injection - Setter 메서드를 이용한 의존성 삽입
    • 의존성을 입력받는 setter 메서드를 만들고 이를 통해 의존성을 주입
  2. Constructor Injection - 생성자를 이용한 의존성 삽입
    • 필요한 의존성을 포함하는 클래스의 생성자를 만들고 이를 통해 의존성을 주입한다.
  3. Method Injection - 일반 메서드를 이용한 의존성 삽입
    • 의존성을 입력 받는 일반 메서드를 만들고 이를 통해 의존성을 주입한다.

DI를 이용한 클래스 호출방식

클래스가 구현 클래스를 사용한다고 했을 떄, DI를 이용하면 구현 클래스를 바로 의존하는 것이 아닌, 상위 인터페이스만 사용하게 된다.

구현 클래스에 대한 정보는 XML이나 annotation과 같은 설정 파일에 개발자가 기술해 둔다.

그렇게 되면 프레임워크(컨테이너)가 설정 파일을 읽은 뒤에 구현 객체를 생성 후, 의존 관계가 있다는 걸 설정한다.

Setter Injection

Hello.java

package bean;

import java.util.LIst;

public class Hello {
    String name;
    Printer printer;

    public Hello() {}

    public void setName(String name) { this.name = name; }
    public void setPrinter(Printer printer) { this.printer = printer; }
}

Hello 가 StringPrinter 를 의존하게 되는 것이다. (new String Printer 는 어디에도 존재하지 않음)
멤버변수인 Printer printer 를 상단에 설정해 두고, setter 메서드를 선언해둔다.

beans.xml

<bean id="hello" class="bean.Hello">
    <property name="name", value="Spring"/>
    <property name="printer" ref="printer"/>
</bean>

<bean id="printer" class="bean.StringPrinter"/>
<bean id="consolePrinter" class="bean.Console.Printer"/>

bean.xml 에 의존관계에 대한 설정을 해둔 것이다.
bean 은 스프링이 관리해주는 객체라는 뜻으로 받아들이면 된다.
Hello.java 의 setter 메서드와 mapping 되는 태그가 bean.xml의 property 태그라고 보면 된다.
첫번째 property 는 Spring 의 값(value)를 넣고, 두번째 property 는 타입에 해당하는 객체인 printer 를 넣는다.
객체 printer 의 경우아래에 id=printer class="bean.StringPrinter" 라고 위치를 지정해둔다.
bean 의 Setter Injection 은 한 번에 한 개씩 의존관계를 주입받을 수 있다.

Constructor Injection

Hello.java

package bean;

import java.util.LIst;

public class Hello {
    String name;
    Printer printer;

    public Hello(String name, Printer printer) {
        this.name = name;
        this.printer = printer;
    }
}

Constructor Injection 은 Setter Injection 과 다르게, 한 번에 여러개의 인자를 받을 수 있다.
Hello 클래스 안에, 생성자를 선언한다. 이후에 설정파일에서 그 값을 지정한다.

beans.xml

<bean id="hello" class="bean.Hello">
    <constructor-arg index="0" value="Spring"/>
    <constructor-arg index="1" ref="printer"/>
</bean>

<bean id="printer" class="bean.StringPrinter"/>
<bean id="consolePrinter" class="bean.Console.Printer"/>

bean.xml 에 위의 Hello.java 와의 의존관계에 대한 설정을 해둔 것이다.
첫번째 인자는 constructor-arg 에 index=0 (배열이기 때문에), value 값을 넣고, 두번쨰 인자에는 index=1, 타입에 해당하는 객체 (StringPrinter)를 적어둔다.
위의 Setter Injection 과 동일하게, printer 객체에 대한 정보는 bean id="printer" 에 적어둔 주소를 이용한다.

'Java, Spring > 개념정리' 카테고리의 다른 글

AOP(Aspect Oriented Programming)  (0) 2023.01.12
DI Container  (0) 2023.01.12
DI, IoC, Container  (0) 2023.01.10
관심사의 분리, MVC 패턴  (0) 2022.08.21
액션태그  (0) 2022.08.16

+ Recent posts