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:

Java
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;
    }
}
Kotlin
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:

Java
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;
    }
}
Kotlin
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:

Java
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;
    }
}
Kotlin
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.