Spring IoC контейнер: внедрение зависимостей на основе конструктора, разрешение аргумента конструктора

Соответствие разрешения аргумента конструктора происходит с использованием типа аргумента. Если в аргументах конструктора определения компонента не существует потенциальной неоднозначности, порядок, в котором аргументы конструктора определяются в определении компонента, является порядком, в котором эти аргументы передаются соответствующему конструктору при создании экземпляра компонента. Рассмотрим следующий класс:

Java

package x.y;

public class ThingOne {

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

Kotlin

package x.y

class 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>, Spring не может определить тип значения и поэтому не может сопоставляться по типу без помощи. Рассмотрим следующий класс:

Java

package examples;

public class ExampleBean {

    // Количество лет для расчета окончательного ответа
    private int years;

    // Ответ жизни, вселенной и всему
    private String ultimateAnswer;

    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}

Kotlin

package examples

class ExampleBean(
    private val years: Int, // Количество лет для расчета окончательного ответа
    private val ultimateAnswer: String// Ответ жизни, вселенной и всему
)

Соответствие типа аргумента конструктора

В предыдущем сценарии контейнер может использовать сопоставление типов с простыми типами, если вы явно указываете тип аргумента конструктора с помощью атрибута type, как показано в следующем примере:

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-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 (начинается с 0).

Имя аргумента конструктора

Вы также можете использовать имя (name) параметра конструктора для устранения неоднозначности значений, как показано в следующем примере:

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

Имейте в виду, что для того, чтобы это работало "из коробки", ваш код должен быть скомпилирован с включенным флагом отладки (debug), чтобы Spring мог искать имя параметра в конструкторе. Если вы не можете или не хотите компилировать свой код с флагом отладки, вы можете использовать аннотацию @ConstructorProperties JDK для явного именования аргументов вашего конструктора. Образец класса должен выглядеть следующим образом:

Java

package examples;

public class ExampleBean {

    // Поля опущены

    @ConstructorProperties({"years", "ultimateAnswer"})
    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}

Kotlin

package examples

class ExampleBean
@ConstructorProperties("years", "ultimateAnswer")
constructor(val years: Int, val ultimateAnswer: String)


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки