본문 바로가기

SpringFramework Core - I. IoC 컨테이너/4. 의존성

4.1.4. 의존성 주입의 예시

원문: https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-some-examples

 

 

다음 예시들은 setter 기반의 의존성 주입을 위해 XML 기반의 설정 메타데이터를 사용하고 있다. 스프링 XML 설정 파일의 일부분에서 몇몇 bean 정의들을 특정하고 있다.

<bean id="exampleBean" class="examples.ExampleBean">
    <!-- ref 요소를 포함하여 setter 주입 -->
    <property name="beanOne">
        <ref bean="anotherExampleBean" />
    </property>
    
    <!-- 더 깔끔한 ref 속성을 사용하여 setter 주입 -->
    <property name="beanTwo" ref="yetAnotherBean" />
    <property name="integerProperty" value="1" />
</bean>


<bean id="anotherExampleBean" class="examples.AnotherBean" />
<bean id="yetAnotherBean" class="examples.YetAnotherBean" />

다음 예시는 위에 따르는 ExampleBean 클래스이다.

public class ExampleBean {

    private AnotherBean beanOne;
    private YetAnotherBean beanTwo;
    private int i;
    
    public void setBeanOne(AnotherBean beanOne) {
        this.beanOne = beanOne;
    }
    
    public void setBeanTwo(YetAnotherBean beanTwo) {
        this.beanTwo = beanTwo;
    }
    
    public void setIntegerProperty(int i) {
        this.i = i;
    }
}

위의 예시에서 setter는 XML 파일에 특정한 프로퍼티와 매칭되도록 선언되어있다.

 

다음 예시는 생성자 기반의 의존성 주입이다.

<bean id="exampleBean" class="examples.ExampleBean">
    <!-- ref 요소를 포함하여 생성자 주입 -->
    <constructor-arg>
        <ref bean="anotherExampleBean" />
    </constructor-arg>
    
    <!-- 더 깔끔한 ref 속성을 사용하여 생성자 주입 -->
    <constructor-arg ref="yetAnotherBean" />
    <constructor-arg type="int" value="1" />
</bean>


<bean id="anotherExampleBean" class="examples.AnotherBean" />
<bean id="yetAnotherBean" class="examples.YetAnotherBean" />

다음 예시는 위에 따르는 ExampleBean 클래스이다.

public class ExampleBean {

    private AnotherBean beanOne;
    private YetAnotherBean beanTwo;
    private int i;
    
    public ExampleBean(AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {
        this.beanOne = anotherBean;
        this.beanTwo = yetAnotherBean;
        this.i = i;
    }
}

bean 정의에 특정된 생성자 매개변수들이 ExampleBean의 생성자 매개변수로 사용되었다. 

 

이제 이 예시의 변형된 형태를 생각해보자. 생성자 방식을 사용하는 것 대신에 인스턴스를 반환받기 위해 스프링이 static 팩토리 메서드를 호출하게 해보자.

<bean id="exampleBean" class="examples.ExampleBean" factory-method="createInstance">
    <constructor-arg ref="anotherExampleBean" />
    <constructor-arg ref="yetAnotherBean" />
    <constructor-arg value="1" />
</bean>


<bean id="anotherExampleBean" class="examples.AnotherBean" />
<bean id="yetAnotherBean" class="examples.YetAnotherBean" />

다음 예시는 위에 따르는 ExampleBean 클래스이다.

public class ExampleBean {

    // private 생성자
    private ExampleBean(...) {
        ...
    }
    
    // static 팩토리 메서드
    // 실제로 변수들이 얼마나 사용되는지와는 상관없이,
    // 이 메서드를 호출하기 위해 제공되는 변수들은 반환되는 bean의 의존성으로 간주된다.
    public static ExampleBean createInstance
                   (AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {
        
        ExampleBean eb = new ExampleBean(...);
        
        // 다른 코드들...
        
        return eb;
    }
}

 

<constructor-arg/> 요소를 통해 제공받는 static 팩토리 메서드의 인자들은 마치 생성자였다면 사용했을 인자들과 정확히 일치한다. 팩토리 메서드를 통해 반환되는 클래스의 타입이 반드시 static 팩토리 메서드를 포함하고 클래스와 같은 타입일 필요는 없다(위 예시에서는 같은 타입으로 반환되고 있지만..). non-static한 인스턴스 팩토리 메서드는 class 속성이 아니라 factory-bean 속성을 쓴다는 점만 제외하고는 본질적으로 동일한 방법으로 사용된다. 따라서 여기서 자세한 사항을 논하지는 않겠다.