У цьому прикладі використовуються конфігураційні метадані на основі 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
), тому ці нюанси тут не розглядаються.