Spring IoC контейнер: примеры внедрения зависимостей

В следующем примере используются метаданные конфигурации на основе XML для DI на основе сеттера. Небольшая часть конфигурационного файла Spring XML определяет некоторые определения bean-компонентов следующим образом:

<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:

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
}

В предыдущем примере сеттеры объявляются как совпадающие со свойствами, указанными в файле 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:

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)

Аргументы конструктора, указанные в определении компонента, используются в качестве аргументов для конструктора 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:

Java

public class ExampleBean {

    // приватный конструктор
    private ExampleBean(...) {
        ...
    }

    // статический фабричный метод; аргументы этого метода могут быть
    // учел зависимости возвращаемого компонента,
    // независимо от того, как эти аргументы фактически используются.
    public static ExampleBean createInstance (
        AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {

        ExampleBean eb = new ExampleBean (...);
        // некоторые другие операции...
        return eb;
    }
}

Kotlin

class ExampleBean private constructor() {
    companion object {
        // статический фабричный метод; аргументы этого метода могут быть
        // учел зависимости возвращаемого компонента,
        // независимо от того, как эти аргументы фактически используются.
        fun createInstance(anotherBean: AnotherBean, yetAnotherBean: YetAnotherBean, i: Int): ExampleBean {
            val eb = ExampleBean (...)
            // некоторые другие операции...
            return eb
        }
    }
}

Аргументы статического метода фабрики предоставляются элементами <constructor-arg/>, точно так же, как если бы фактически использовался конструктор. Тип класса, возвращаемого методом фабрики, не обязательно должен быть того же типа, что и класс, содержащий статический метод фабрики (хотя в данном примере это так). Экземплярный (нестатический) фабричный метод может использоваться по существу идентичным способом (за исключением использования атрибута factory-bean вместо атрибута class).


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


Комментарии

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

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

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

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