Сообщения

Показаны сообщения с ярлыком "Dependency Injection"

Spring IoC контейнер: зависимости, инъекция метода, произвольная замена метода

Изображение
Менее полезной формой внедрения метода, чем внедрением метода поиска , является возможность замены произвольных методов в управляемом компоненте другой реализацией метода. С помощью метаданных конфигурации на основе XML вы можете использовать элемент replace-method, чтобы заменить существующую реализацию метода другой, для развернутого компонента. Рассмотрим следующий класс, в котором есть метод computeValue, который мы хотим переопределить: Java public class MyValueCalculator { public String computeValue(String input) { // некоторый реальный код... } // некоторые другие методы... } Kotlin class MyValueCalculator { fun computeValue(input: String): String { // некоторый реальный код... } // некоторые другие методы... } Класс, который реализует интерфейс org.springframework.beans.factory.support.MethodReplacer, предоставляет определение нового метода, как показано в следующем примере: Java /** * предназначен для переопреде...

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

Изображение
Инъекция метода поиска (Lookup method injection) - это способность контейнера переопределять методы в управляемых контейнером bean-компонентах и ​​возвращать результат поиска для другого именованного bean-компонента в контейнере. Поиск обычно включает в себя прототип bean-компонента, как в сценарии, описанном в предыдущем посте . Spring Framework реализует внедрение этого метода, используя генерацию байт-кода из библиотеки CGLIB для динамической генерации подкласса, который переопределяет метод. Чтобы этот динамический подкласс работал, класс, который является подклассом контейнера bean-компонента Spring, не может быть окончательным (final), и переопределяемый метод также не может быть конечным (final). Модульное тестирование (юнит-тестирование) класса, который имеет абстрактный метод, требует, чтобы вы сами создали подкласс класса и предоставили реализацию-заглушку абстрактного метода. Конкретные методы также необходимы для сканирования компонентов, для которого требуются конкретн...

Spring IoC контейнер: зависимости, инъекция метода

Изображение
В большинстве сценариев применения большинство бинов в контейнере являются синглтонами. Когда синглтону необходимо сотрудничать с другим синглтоном или не-синглтон компоненту необходимо сотрудничать с другим не-синглтон компонентом, вы обычно обрабатываете зависимость, определяя один компонент как свойство другого. Проблема возникает, когда жизненные циклы бинов различны. Предположим, что синглтон компоненту A нужно использовать не-синглтон (прототип) компонент B, возможно, при каждом вызове метода в A. Контейнер создает синглтон компонент A только один раз и, таким образом, получает только одну возможность установить свойства. Контейнер не может предоставить компоненту A новый экземпляр компонента B каждый раз, когда он нужен. Решение состоит в том, чтобы отказаться от некоторой инверсии контроля. Вы можете сделать так, чтобы компонент A узнал о контейнере, реализовав интерфейс ApplicationContextAware и сделав вызов getBean("B") для контейнера, запрашивая (как правило, новы...

Spring IoC контейнер: зависимости и конфигурация в деталях, элемент idref

Изображение
Элемент idref - это просто защищенный от ошибок способ передачи идентификатора (строковое значение - не ссылка) другого компонента в контейнере в элемент <constructor-arg/> или <property/>. В следующем примере показано, как его использовать: <bean id="theTargetBean" class="..."/> <bean id="theClientBean" class="..."> <property name="targetName"> <idref bean="theTargetBean"/> </property> </bean> Предыдущий фрагмент определения компонента в точности соответствует (во время выполнения) следующему фрагменту: <bean id="theTargetBean" class="..." /> <bean id="client" class="..."> <property name="targetName" value="theTargetBean"/> </bean> Первая форма предпочтительнее второй, потому что использование тега idref позволяет контейнеру проверять во время развертывания, чт...

Spring IoC контейнер: зависимости и конфигурация в деталях, прямые значения

Изображение
Как упоминалось в предыдущих постах, вы можете определить свойства компонента и аргументы конструктора как ссылки на другие управляемые компоненты (соавторы) или как значения, определенные внутри строки. Для этого метаданные конфигурации на основе XML в Spring поддерживают типы подэлементов в своих элементах <property/> и <constructor-arg/>. Прямые значения (примитивы, строки и т. д.) Атрибут value элемента <property/> указывает аргумент свойства или конструктора в виде удобочитаемого строкового представления. Служба преобразования Spring используется для преобразования этих значений из строки в фактический тип свойства или аргумента. В следующем примере показаны различные устанавливаемые значения: <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <!-- результаты в setDriverClassName(String) вызове --> <property name="driverClassName" value="com.mysq...

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

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

Изображение
Контейнер выполняет разрешение зависимостей бина следующим образом: ApplicationContext создается и инициализируется с метаданными конфигурации, которые описывают все компоненты. Метаданные конфигурации могут быть указаны с помощью XML, кода Java или аннотаций. Для каждого компонента его зависимости выражаются в форме свойств, аргументов конструктора или аргументов метода статичной фабрики (если вы используете его вместо обычного конструктора). Эти зависимости предоставляются компоненту, когда компонент фактически создается. Каждый аргумент свойства или конструктора является фактическим определением значения, которое нужно установить, или ссылкой на другой компонент в контейнере. Каждый аргумент свойства или конструктора, являющийся значением, преобразуется из указанного формата в фактический тип аргумента этого свойства или конструктора. По умолчанию Spring может преобразовать значение, предоставленное в строковом формате, во все встроенные типы, такие как int, long, String, bool...

Spring IoC контейнер: DI на основе конструктора или сеттера?

Изображение
Поскольку вы можете смешивать DI на основе конструктора и сеттера, рекомендуется использовать конструкторы для обязательных зависимостей, а также методы сеттеры или методы настройки для необязательных зависимостей. Обратите внимание, что использование аннотации @Required в методе сеттере может быть использовано для того, чтобы сделать свойство обязательной зависимостью; однако внедрение в конструктор с программной проверкой аргументов предпочтительнее. Команда Spring, как правило, выступает за внедрение конструктора, поскольку она позволяет реализовывать компоненты приложения как неизменяемые объекты и гарантирует, что требуемые зависимости не равны null. Более того, внедренные конструктором компоненты всегда возвращаются клиентскому (вызывающему) коду в полностью инициализированном состоянии. В качестве примечания следует отметить, что большое количество аргументов конструктора является нежелательным кодом, подразумевая, что класс, вероятно, имеет слишком много обязанностей и должен ...

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

Изображение
DI на основе сеттера выполняется контейнером, вызывающим методы setter для ваших bean-компонентов после вызова конструктора без аргументов или статического метода фабрики без аргументов для создания экземпляра вашего bean-компонента. В следующем примере показан класс, который может быть внедрен зависимостью только при использовании setter внедрения. Этот класс является обычным Java классом. Это POJO, который не зависит от конкретных интерфейсов контейнера, базовых классов или аннотаций. Java public class SimpleMovieLister { // SimpleMovieLister зависит от MovieFinder private MovieFinder movieFinder; // метод сеттер, чтобы контейнер Spring мог внедрить MovieFinder public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // бизнес-логика, которая фактически использует внедренный MovieFinder, опущена... } Kotlin class SimpleMovieLister { // свойство с поздней инициализацией, чтобы контейнер Spring мог внед...

Spring IoC контейнер: внедрение зависимостей на основе конструктора, разрешение аргумента конструктора

Изображение
Соответствие разрешения аргумента конструктора происходит с использованием типа аргумента. Если в аргументах конструктора определения компонента не существует потенциальной неоднозначности, порядок, в котором аргументы конструктора определяются в определении компонента, является порядком, в котором эти аргументы передаются соответствующему конструктору при создании экземпляра компонента. Рассмотрим следующий класс: Java package x.y; public class ThingOne { public ThingOne(ThingTwo thingTwo, ThingThree thingThree) { // ... } } Kotlin package x.y class ThingOne(thingTwo: ThingTwo, thingThree: ThingThree) Предполагая, что классы ThingTwo и ThingThree не связаны наследованием, потенциальной двусмысленности не существует. Таким образом, следующая конфигурация работает нормально, и вам не нужно явно указывать индексы или типы аргументов конструктора в элементе <constructor-arg/>. <beans> <bean id="beanOne" class="x.y.Thi...

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

Изображение
DI на основе конструктора выполняется контейнером, вызывающим конструктор с несколькими аргументами, каждый из которых представляет зависимость. Вызов статического метода фабрики со специфическими аргументами для создания компонента почти эквивалентен, и в этом обсуждении аргументы конструктора и статического метода фабрики аналогичны. В следующем примере показан класс, который может быть внедрен только в зависимости с помощью конструктора: Java public class SimpleMovieLister { // SimpleMovieLister имеет зависимость от MovieFinder private MovieFinder movieFinder; // конструктор, чтобы контейнер Spring мог внедрить MovieFinder public SimpleMovieLister(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // бизнес-логика, которая фактически использует внедренный MovieFinder, опущена ... } Kotlin // конструктор, чтобы контейнер Spring мог внедрить MovieFinder class SimpleMovieLister(private val movieFinder: MovieFinder) { // бизне...

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

Изображение
Типичное корпоративное приложение не состоит из одного объекта (или bean-компонента в Spring). Даже в самом простом приложении есть несколько объектов, которые работают вместе, чтобы представить то, что конечный пользователь видит как связное приложение. В следующих постах объясняется, как перейти от определения отдельных определений bean-компонентов к полностью реализованному приложению, в котором объекты взаимодействуют для достижения цели. Внедрение зависимостей Внедрение зависимостей (DI, Dependency injection) - это процесс, при котором объекты определяют свои зависимости (то есть другие объекты, с которыми они работают) только через аргументы конструктора, аргументы метода фабрики или свойства, которые устанавливаются в экземпляре объекта после его создания или возвращения из фабричного метода. Затем контейнер внедряет эти зависимости при создании компонента. Этот процесс по своей сути является инверсией (отсюда и название, инверсия контроля) самого компонента, самостоятельно к...