В следующем примере используются конфигурационные метаданные на основе XML для DI на основе сеттера. Небольшая часть конфигурационного файла Spring XML задает некоторые определения бинов следующим образом:
<bean id="exampleBean" class="examples.ExampleBean">
<!-- внедрение через сеттер с использованием вложенного элемента ref -->
<property name="beanOne">
<ref bean="anotherExampleBean"/>
</property>
<!-- внедрение через сеттер с использованием более точного атрибута ref -->
<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;
}
}
class ExampleBean {
lateinit var beanOne: AnotherBean
lateinit var beanTwo: YetAnotherBean
var i: Int = 0
}
В предыдущем примере сеттеры объявлены для сопоставления со свойствами, указанными в XML-файле. В следующем примере используется DI на основе конструктора:
<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;
}
}
class ExampleBean(
private val beanOne: AnotherBean,
private val beanTwo: YetAnotherBean,
private val i: Int)
Аргументы конструктора, заданные в определении бина, используются в качестве аргументов конструктора ExampleBean
.
Теперь рассмотрим вариант этого примера, в котором вместо использования конструктора Spring предлагается вызвать ститический
фабричный метод для возврата экземпляра объекта:
<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 ExampleBean(...) {
...
}
// статический фабричный метод; аргументами этого метода могут считаться
// зависимости возвращаемого бина,
// независимо от того, как эти аргументы фактических используются.
public static ExampleBean createInstance (
AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {
ExampleBean eb = new ExampleBean (...);
// некоторые другие операции...
return eb;
}
}
class ExampleBean private constructor() {
companion object {
// статический фабричный метод; аргументами этого метода могут считаться
// зависимости возвращаемого бина,
// независимо от того, как эти аргументы фактических используются.
@JvmStatic
fun createInstance(anotherBean: AnotherBean, yetAnotherBean: YetAnotherBean, i: Int): ExampleBean {
val eb = ExampleBean (...)
// некоторые другие операции...
return eb
}
}
}
Аргументы для статического
фабричного метода предоставляются элементами <constructor-arg/>
, точно так же, как если бы на самом деле использовался конструктор. Тип класса, возвращаемого фабричным методом, не обязательно должен быть того же типа, что и класс, содержащий статический
фабричный метод (хотя в данном примере это так). Экземплярный (нестатический) фабричный метод может быть использован практически идентичным образом (за исключением использования атрибута factory-bean
вместо атрибута class
), поэтому здесь эти нюансы не рассматриваются.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ