본문 바로가기

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

4.1.2. 생성자 매개변수 해석

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

 

 

생성자 매개변수 매칭은 매개변수의 타입을 통해 이루어진다. 만약 bean 정의에서 생성자 매개변수들에 대한 아무런 잠재적인 애매함이 없다면, 생성자 매개변수들이 정의된 순서가 곧 bean이 인스턴스화 될 때 생성자에 공급되는 인자들의 순서가 된다. 다음 클래스를 참고하라.

package x.y;

public class ThingOne {

     public ThingOne(ThingTwo thingTwo, ThingThree thingThree) {
          // ...
     }
}

ThingTwo와 ThingThree 클래스가 상속으로 관련된 것들이 아니라고 가정하면, 아무런 잠재적인 애매함이 없다. 따라서 위 설정은 잘 작동한다. 또한 <constructor-arg /> 요소 안에서 생성자 매개변수의 인덱스를 설정하거나 명확하게 타입을 설정해 줄 필요가 없다. 

<beans>
    <bean id="beanOne" class="x.y.ThingOne">
        <constructor-arg ref="beanTwo" />
        <constructor-arg ref="beanThree" />
    </bean>
    
    <bean id="beanTwo" class="x.y.ThingTwo" />
    
    <bean id="beanThree" class="x.y.ThingThree" />
</beans>

타입이 알려진 다른 bean이 참조되었을 때, 매칭이 이루어진다. <value>true</value>와 같은 간단한 타입이 사용되었을 때, 스프링은 value의 타입을 결정하지 못한다. 그래서 도움없이는 타입을 매치할 수 없게 된다. 다음 클래스를 참고하라.

package examples;

public class ExampleBean {

    // 최종적인 답을 계산하기 위한 연도
    private int years;
    
    // 삶, 우주, 그리고 모든 것들에 대한 답
    private String ultimateAnswer;
    
    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}

 

생성자 매개변수 타입 매칭

위의 예시에서, 'type' 속성을 통해서 생성자 매개변수의 타입을 명확히 특정해줬다면, 컨테이너는 간단한 타입들을 통해서도 타입 매칭을 사용할 수 있을 것이다. 다음 예시를 보자.

<bean id="exampleBean" class="examples.ExampleBean">
    <contructor-arg type="int" value="7500000" />
    <contructor-arg type="java.lang.String" value="42" />
</bean>

 

생성자 매개변수 인덱스

'index' 속성을 이용해 생성자 매개변수의 인덱스를 명확하게 특정할 수도 있다. 다음 예시를 보자.

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000" />
    <constructor-arg index="1" value="42" />
</bean>

 

생성자가 같은 타입의 매개변수를 두 개 갖는 곳처럼, 간단한 값들이 갖는 애매함을 해결하려 할때도 인덱스를 특정하면 된다. 

 

※ 인덱스는 0번부터 시작한다.

 

생성자 매개변수의 이름

값의 애매함을 없애기 위하여 생성자 매개변수의 이름 또한 사용할 수 있다. 다음 예시를 보자.

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg name="years" value="7500000" />
    <constructor-arg name="ultimateAnswer" value="42" />
</bean>

만약 위의 박스가 실행되도록 만들려면, 스프링이 생성자의 매개변수 이름을 찾아볼 수 있도록 디버그 플래그가 사용가능하도록 컴파일되어야 한다는 점을 기억하라. 만약 디버그 플래그로 코드를 컴파일할 수 없거나 그렇게 하기 싫다면 @ConstructorProperties라는 JDK의 어노테이션에 생성자 매개변수들의 이름을 명확히 붙여주면 된다. 다음 예시를 참고하라.

package examples;

public class ExampleBean {

    // 필드는 생략
    
    @ConstructorProperties({"years", "ultimateAnswer"})
    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}