JavaRush/Курсы/Модуль 5. Spring/Примеры внедрения зависимостей

Примеры внедрения зависимостей

Открыта

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

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 {
        // статический фабричный метод; аргументами этого метода могут считаться
        // зависимости возвращаемого бина,
        // независимо от того, как эти аргументы фактических используются.
        @JvmStatic
        fun createInstance(anotherBean: AnotherBean, yetAnotherBean: YetAnotherBean, i: Int): ExampleBean {
            val eb = ExampleBean (...)
            // некоторые другие операции...
            return eb
        }
    }
}

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

Комментарии (10)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Родион
Уровень 113
14 августа 2025, 15:05
ститический фабричный метод
Сергей
Уровень 21
22 марта 2023, 18:30
и на сколько вобще актульно щас в xml изучать это все? здается мне что нам впаривают какую то дичь
Эльвинастранник в дом
14 июня 2023, 13:12
я сейчас работаю в организации, дали проект, а там все бины в xml, так что такое тоже можно встретить, оказывается)
11 сентября 2023, 11:34
Багато ентепрайзів працюють на застралілому коді, який не бачив рефактору роками. Тому якщо потрапите у компанію яка пітримує такий проект, то доведеться стикатися із такими динозаврами.
hidden #2513091
Уровень 44
24 февраля 2023, 04:04
После долгого изучения различной поверхностной информации, этот курс очень помогает расставить все по местам.
Will Fight
Уровень 27
16 февраля 2023, 12:35
ститический фабричный метод
Igor
Уровень 2
Expert
10 февраля 2023, 03:31
Почему в первом примере, когда используем сеттеры, то имя в xml :
<property name="integerProperty" value="1"/>
не совпадает с именем поля в самом классе:
private int i;
хотя имена первых двух полей одинаковые
12 февраля 2023, 11:53
Если мне не изменяет память, то в xml имя можно любое задавать, с полем не обязано совпасть. Когда класс правильно помечен, там Спринг сам поймет, кто есть кто.
Денис
Уровень 108
Expert
13 февраля 2023, 21:24
Потому что мы должны СТРОГО использовать имя сеттера, без слова set и с маленькой буквы. Спринг сам добавляет set и делает маленькую букву заглавной. Вот как в этой статье. public void setIntegerProperty(int i) { this.i = i; } <property name="integerProperty" value="1"/> Другой пример, если бы у нас был такой сеттер public void setWhatYouWant(int i) { this.i = i; } То XML была бы такой <property name="whatYouWant" value="1"/>
Igor
Уровень 2
Expert
14 февраля 2023, 00:49
Спасибо большое за ответы! Стало понятнее теперь. Получается Спринг смотрит на имя сеттера и сравнивает его с property name в xml файле, т.е. ему все равно как это поле называется в самом классе.