Каждое Java-приложение имеет несколько объектов, которые работают вместе, чтобы представить то, что конечный пользователь видит в качестве рабочего приложения. При написании сложного Java-приложения классы приложения должны быть как можно более независимыми от других Java-классов, чтобы увеличить возможность повторного использования этих классов и тестировать их независимо от других классов во время модульного тестирования. Инъекция зависимостей (или иногда называемая проводкой) помогает склеивать эти классы и в то же время сохранять их независимость.
Предположим, у вас есть приложение, в котором есть компонент текстового редактора, и вы хотите обеспечить проверку орфографии. Ваш стандартный код будет выглядеть примерно так:
public class TextEditor { private SpellChecker spellChecker; public TextEditor() { spellChecker = new SpellChecker(); } }
Здесь мы создали зависимость между TextEditor и SpellChecker. В сценарии инверсии управления мы вместо этого сделали бы что-то вроде этого —
public class TextEditor { private SpellChecker spellChecker; public TextEditor(SpellChecker spellChecker) { this.spellChecker = spellChecker; } }
Здесь TextEditor не должен беспокоиться о реализации SpellChecker. SpellChecker будет реализован независимо и будет предоставлен TextEditor во время создания экземпляра TextEditor. Вся эта процедура контролируется Spring Framework.
Здесь мы удалили тотальный контроль из TextEditor и сохранили его где-то еще (например, файл конфигурации XML), а зависимость (т.е. класс SpellChecker) вводится в класс TextEditor через конструктор класса . Таким образом, поток управления был «инвертирован» с помощью Dependency Injection (DI), потому что вы фактически делегировали зависимости некоторой внешней системе.
Второй метод внедрения зависимости — через Setter Methods класса TextEditor, где мы создадим экземпляр SpellChecker. Этот экземпляр будет использоваться для вызова методов установки для инициализации свойств TextEditor.
Таким образом, DI существует в двух основных вариантах, и в следующих двух подразделах будут рассмотрены оба примера:
Sr.No. | Тип и описание внедрения зависимостей |
---|---|
1 | Внедрение зависимостей на основе конструктора
DI на основе конструктора выполняется, когда контейнер вызывает конструктор класса с несколькими аргументами, каждый из которых представляет зависимость от другого класса. |
2 | Внедрение зависимостей на основе установки
DI на основе установки выполняется контейнером, вызывающим методы setter для ваших bean-компонентов после вызова конструктора без аргументов или статического метода фабрики без аргументов для создания экземпляра вашего bean-компонента. |
DI на основе конструктора выполняется, когда контейнер вызывает конструктор класса с несколькими аргументами, каждый из которых представляет зависимость от другого класса.
DI на основе установки выполняется контейнером, вызывающим методы setter для ваших bean-компонентов после вызова конструктора без аргументов или статического метода фабрики без аргументов для создания экземпляра вашего bean-компонента.
Вы можете смешивать как DI на основе конструктора, так и на основе Setter, но рекомендуется использовать аргументы конструктора для обязательных зависимостей и setters для необязательных зависимостей.
Код чище с принципом DI, и разъединение более эффективно, когда объектам предоставлены их зависимости. Объект не просматривает свои зависимости и не знает местоположения или класса зависимостей, скорее всего Spring Framework позаботится обо всем.