Spring IoC контейнер: зависимости, инъекция метода
В большинстве сценариев применения большинство бинов в контейнере являются синглтонами. Когда синглтону необходимо сотрудничать с другим синглтоном или не-синглтон компоненту необходимо сотрудничать с другим не-синглтон компонентом, вы обычно обрабатываете зависимость, определяя один компонент как свойство другого. Проблема возникает, когда жизненные циклы бинов различны. Предположим, что синглтон компоненту A нужно использовать не-синглтон (прототип) компонент B, возможно, при каждом вызове метода в A. Контейнер создает синглтон компонент A только один раз и, таким образом, получает только одну возможность установить свойства. Контейнер не может предоставить компоненту A новый экземпляр компонента B каждый раз, когда он нужен.
Решение состоит в том, чтобы отказаться от некоторой инверсии контроля. Вы можете сделать так, чтобы компонент A узнал о контейнере, реализовав интерфейс ApplicationContextAware и сделав вызов getBean("B") для контейнера, запрашивая (как правило, новый) экземпляр компонента B каждый раз, когда это требуется компоненту A. В следующем примере показан этот подход:
Java
// класс, который использует класс с состоянием Command-style для выполнения некоторой обработки
package fiona.apple;
// Spring-API imports
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class CommandManager implements ApplicationContextAware {
private ApplicationContext applicationContext;
public Object process(Map commandState) {
// захватить новый экземпляр соответствующего Command
Command command = createCommand();
// устанавливаем состояние (ожидаемо, нового) экземпляра Command
command.setState(commandState);
return command.execute();
}
protected Command createCommand() {
// обратите внимание на Spring API зависимость!
return this.applicationContext.getBean("command", Command.class);
}
public void setApplicationContext(
ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
Kotlin
// класс, который использует класс с состоянием Command-style для выполнения некоторой обработки
package fiona.apple
// Spring-API imports
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
class CommandManager : ApplicationContextAware {
private lateinit var applicationContext: ApplicationContext
fun process(commandState: Map<*, *>): Any {
// захватить новый экземпляр соответствующего Command
val command = createCommand()
// устанавливаем состояние (ожидаемо, нового) экземпляра Command
command.state = commandState
return command.execute()
}
// обратите внимание на Spring API зависимость!
protected fun createCommand() =
applicationContext.getBean("command", Command::class.java)
override fun setApplicationContext(applicationContext: ApplicationContext) {
this.applicationContext = applicationContext
}
}
Предыдущее нежелательно, поскольку бизнес-код осведомлен о Spring Framework и связан с ним. Внедрение метода, несколько расширенная функция контейнера IoC Spring, позволяет аккуратно обрабатывать этот сценарий использования.
Читайте также:
- Spring IoC контейнер: зависимости, лениво инициализированные бины
- Spring IoC контейнер: зависимости и конфигурация в деталях, ярлык XML с пространством имен p
- Spring IoC контейнер: зависимости, автопривязка взаимодействующих компонентов
Комментарии
Отправить комментарий