The following example uses XML-based configuration metadata for setter-based DI. A small part of the Spring XML configuration file specifies some bean definitions as follows:
<bean id="exampleBean" class="examples.ExampleBean">
<!-- injection via setter using a nested ref element -->
<property name="beanOne">
<ref bean="anotherExampleBean"/>
</property>
<!-- injection via setter using the more precise ref attribute -->
<property name="beanTwo" ref="yetAnotherBean"/>
<property name="integerProperty" value="1"/>
</bean>
<bean id="anotherExampleBean" class="examples.AnotherBean"/>
<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
The following example shows the corresponding ExampleBean
class:
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
}
In the previous example, setters are declared to map to properties specified in the XML file. The following example uses constructor-based DI:
<bean id="exampleBean" class="examples.ExampleBean">
<!-- constructor injection using a nested ref element -->
<constructor-arg>
<ref bean="anotherExampleBean"/>
</constructor-arg>
<!-- constructor injection using the more precise ref attribute -->
<constructor-arg ref="yetAnotherBean"/>
<constructor-arg type="int" value="1"/>
</bean>
<bean id="anotherExampleBean" class="examples.AnotherBean"/>
<bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
The following example shows the corresponding ExampleBean
class:
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)
Constructor arguments specified in the bean definition are used as arguments to the ExampleBean
constructor.
Now consider a variation of this example that, instead of using a Spring constructor, calls a static
factory method to return an instance of the object:
<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"/>
The following example shows the corresponding ExampleBean
class:
public class ExampleBean {
// private (private) constructor
private ExampleBean(...) {
...
}
// static factory method; the arguments of this method can be considered
// dependencies of the returned bean,
// no matter how these arguments are actually used.
public static ExampleBean createInstance (
AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {
ExampleBean eb = new ExampleBean(...);
// some other operations...
return eb;
}
}
class ExampleBean private constructor() {
companion object {
// static factory method; the arguments of this method can be considered
// dependencies of the returned bean,
// no matter how these arguments are actually used.
@JvmStatic
fun createInstance(anotherBean: AnotherBean, yetAnotherBean: YetAnotherBean, i: Int): ExampleBean {
val eb = ExampleBean(...)
// some other operations...
return eb
}
}
}
Arguments to a static
factory method are provided by <constructor-arg/>
elements, just as if a constructor were actually being used. The type of the class returned by the factory method does not have to be the same type as the class containing the static
factory method (although it is in this example). An instance (non-static) factory method can be used in an almost identical manner (except for using the factory-bean
attribute instead of the class
attribute), so these nuances are not covered here.
GO TO FULL VERSION