Что такое внедрение зависимостей и инверсия управления в Spring Framework?

«Внедрение зависимостей» и «инверсия управления» часто упоминаются как основные преимущества использования среды Spring для разработки веб-платформ.

Может ли кто-нибудь объяснить, что это такое, очень простым языком, если возможно?


person Chillax    schedule 22.02.2012    source источник
comment
возможный дубликат Что такое инверсия управления?   -  person Steve Chambers    schedule 24.04.2014
comment
@SteveChambers это не дубликат, этот вопрос задают в Springs Perspective. Этот вопрос в целом предварительный.   -  person VeKe    schedule 27.03.2015
comment
stackoverflow.com/questions/57386896/   -  person nitinsridar    schedule 07.08.2019


Ответы (11)


  • Spring помогает в создании слабосвязанных приложений благодаря внедрению зависимостей.
  • В Spring объекты определяют свои ассоциации (зависимости) и не беспокоятся о том, как они получат эти зависимости. Spring отвечает за предоставление необходимых зависимостей для создания объектов.

Например: предположим, что у нас есть объект Employee, который зависит от объекта Address. Мы бы определили bean-компонент, соответствующий Employee, который будет определять его зависимость от объекта Address.

Когда Spring пытается создать объект Employee, он увидит, что Employee имеет зависимость от Address, поэтому сначала создаст объект Address (зависимый объект), а затем внедрит его в объект Employee.

  • Инверсия управления (IoC) и внедрение зависимостей (DI) используются как взаимозаменяемые. IoC достигается через DI. DI - это процесс предоставления зависимостей, а IoC - конечный результат DI. (Примечание. DI - не единственный способ достичь IoC. Есть другие способами.)

  • Благодаря DI ответственность за создание объектов перекладывается с кода нашего приложения на контейнер Spring; это явление называется IoC.

  • Внедрение зависимостей может быть выполнено путем внедрения установщика или конструктора.
person Krishnakant Kadam    schedule 23.01.2014
comment
Я не согласен. я не думаю, что это ясное объяснение. Почему вы не можете просто создать экземпляр Address внутри Employee вместо того, чтобы получить фреймворк для его создания и внедрения? Требуется чуть более подробный пример. - person Boris; 20.10.2018
comment
@Boris Никто не говорил, что вы не можете создавать свои собственные объекты. Но единственной целью ответа было продемонстрировать, как можно добиться того же с помощью DI. Клиентский код может создавать экземпляры как DI, так и объектов. Это по-прежнему будет называться МОК, по крайней мере частично. - person bogdan.rusu; 27.01.2019
comment
stackoverflow.com/questions/57386896/ - person nitinsridar; 07.08.2019
comment
Борис. Очень ревнивый? Это лучший ответ на свете. - person Aniket Kapse; 08.04.2020

Я запишу свое простое понимание этих двух терминов: (для быстрого понимания просто прочтите примеры)

  • Внедрение зависимостей (DI):
    Внедрение зависимостей обычно означает передачу зависимого объекта в качестве параметра методу вместо того, чтобы метод создавал зависимый объект.
    На практике это означает, что метод не имеет прямой зависимости от конкретной реализации; любая реализация, отвечающая требованиям, может быть передана в качестве параметра.

    С помощью этой реализации объекты определяют их зависимости. И весна делает это доступным.
    Это приводит к разработке слабосвязанных приложений.

    Быстрый пример: ОБЪЕКТ СОТРУДНИКА ПРИ СОЗДАНИИ, ОН АВТОМАТИЧЕСКИ СОЗДАЕТ ОБЪЕКТ АДРЕСА (если адрес определен как зависимость объектом Сотрудника) *.

  • Контейнер инверсии управления (IoC):
    Это общая характеристика фреймворков. IoC управляет объектами Java
    - от создания до уничтожения с помощью своей BeanFactory.
    - Компоненты Java, экземпляры которых создаются контейнером IoC, называются bean-компонентами, а контейнер IoC управляет областью bean-компонента, событиями жизненного цикла и любыми функциями AOP, для которых он был настроен и закодирован. < br>
    QUICK EXAMPLE:Inversion of Control is about getting freedom, more flexibility, and less dependency. When you are using a desktop computer, you are slaved (or say, controlled). You have to sit before a screen and look at it. Using keyboard to type and using mouse to navigate. And a bad written software can slave you even more. If you replaced your desktop with a laptop, then you somewhat inverted control. You can easily take it and move around. So now you can control where you are with your computer, instead of computer controlling it.

    Реализуя инверсию управления, потребитель программного обеспечения / объекта получает больше элементов управления / опций по сравнению с программным обеспечением / объектами вместо того, чтобы быть управляемым или иметь меньше опций.

    Инверсия управления в качестве руководства по проектированию служит следующим целям:
    - Существует разделение выполнения определенной задачи от реализации.
    - Каждый модуль может сосредоточиться на том, для чего они предназначены.
    - Модули не делают предположений о том, что делают другие системы, а полагаются на их контракты.
    - Замена модулей не оказывает побочного эффекта на другие модули

Здесь я буду говорить абстрактно, вы можете перейти по следующим ссылкам для более детального понимания темы.

Хорошее чтение с примером

Подробное объяснение

person VeKe    schedule 10.11.2014

В Spring объекты слабо связаны, то есть каждый класс не зависит друг от друга, поэтому все можно тестировать индивидуально. Но при использовании этих классов класс может зависеть от других классов, которые необходимо создать в первую очередь.

Итак, мы сообщаем Spring, что класс A зависит от класса B. Итак, при создании bean-компонента (например, класса) для класса A он создает экземпляр класса B до класса A и внедряет его в класс A, используя методы DI установщика или конструктора. То есть мы сообщаем Spring о зависимости во время выполнения. Это Д.И.

Поскольку мы возлагаем ответственность за создание объектов (bean-компонентов), их обслуживание и их агрегаты на Spring вместо жесткого программирования, мы называем это инверсией управления (IOC).

person Venkateswara Rao    schedule 27.04.2017

Инверсия управления - это означает передачу управления созданием и инстанцированием компонентов Spring в контейнер Spring IOC, и единственная работа, которую выполняет разработчик, - это настройка bean-компонентов в XML-файле Spring.

Внедрение зависимости-

Рассмотрим класс Employee

class Employee { 
   private int id;
   private String name;
   private Address address;

   Employee() {
     id = 10;
     name="name";
     address = new Address();
   }


}

и рассмотрим класс Address

class Address {
   private String street;
   private String city;

   Address() {
     street="test";
     city="test1";

  }
}

В приведенном выше коде значения класса адреса будут установлены только при создании экземпляра класса Employee, что является зависимостью класса Address от класса Employee. Spring решает эту проблему, используя концепцию внедрения зависимостей, предоставляя два способа внедрения этой зависимости.

  1. Инъекция сеттера

Метод Setter в классе Employee, который принимает ссылку на класс Address

public void setAddress(Address addr) {
    this.address = addr;
}
  1. Внедрение конструктора

Конструктор в классе Employee, который принимает Address

Employee(Address addr) {
      this.address = addr;
}

Таким образом, значения класса Address могут быть установлены независимо с помощью внедрения либо установщика / конструктора.

person Hetal Rachh    schedule 27.06.2018

Spring: Spring - это контейнер «инверсии управления» для платформы Java.

Инверсия управления (IoC): Инверсия управления (IoC) - это практика объектно-ориентированного программирования, при которой связывание объектов ограничивается во время выполнения «ассемблерным» объектом и, как правило, неизвестно во время компиляции с использованием статического анализа.

Внедрение зависимостей (DI): «Внедрение зависимостей - это шаблон проектирования программного обеспечения, который позволяет удалять жестко запрограммированные зависимости и дает возможность изменять их, будь то во время выполнения или во время компиляции». -wiki.

person Nadhu    schedule 16.02.2016
comment
Как это может быть проще, чем то, что уже есть (откуда этот ответ)? Он не учитывает просьбу OP о простоте, если только двойные кавычки вокруг терминологии волшебным образом не упрощают задачу. - person Flame of udun; 05.10.2018

Инверсия управления (IOC):

IoC - это шаблон проектирования, который описывает инверсию потока управления в системе, поэтому поток выполнения не контролируется центральным фрагментом кода. Это означает, что компоненты должны зависеть только от абстракций других компонентов и не нести ответственности за создание зависимых объектов. Вместо этого экземпляры объектов предоставляются во время выполнения контейнером IoC через внедрение зависимостей (DI).

IoC позволяет улучшить разработку программного обеспечения, что облегчает повторное использование, слабую связь и легкое тестирование программных компонентов.

Внедрение зависимостей (DI):

DI - это метод передачи зависимостей в конструктор объекта. Если объект был загружен из контейнера, то его зависимости будут автоматически предоставлены контейнером. Это позволяет использовать зависимость без необходимости вручную создавать экземпляр. Это уменьшает взаимосвязь и дает вам больший контроль над временем жизни экземпляров объекта.

нажмите, чтобы увидеть больше

person Greesh Kumar    schedule 10.10.2017

Инверсия управления - это общий принцип построения архитектуры программного обеспечения, который помогает в создании многократно используемых модульных программных сред, которые легко поддерживать.

Это принцип проектирования, в котором поток управления «принимается» из библиотеки общего назначения или повторно используемого кода.

Чтобы лучше понять это, давайте посмотрим, как мы кодировали в первые дни кодирования. В процедурных / традиционных языках бизнес-логика обычно управляет потоком приложения и «вызывает» общий или повторно используемый код / ​​функции. Например, в простом консольном приложении мой поток управления контролируется инструкциями моей программы, которые могут включать вызовы некоторых общих функций многократного использования.

print ("Please enter your name:");
scan (&name);
print ("Please enter your DOB:");
scan (&dob);

//More print and scan statements
<Do Something Interesting>

//Call a Library function to find the age (common code)
print Age

В отличие от IoC, Frameworks представляют собой повторно используемый код, который «вызывает» бизнес-логику.

Например, в системе на основе Windows уже будет доступна платформа для создания элементов пользовательского интерфейса, таких как кнопки, меню, окна и диалоговые окна. Когда я пишу бизнес-логику своего приложения, это будут события фреймворка, которые будут вызывать мой код бизнес-логики (при срабатывании события), а НЕ наоборот.

Хотя код фреймворка не знает моей бизнес-логики, он все равно знает, как вызывать мой код. Это достигается с помощью событий / делегатов, обратных вызовов и т. Д. Здесь управление потоком «Инвертировано».

Таким образом, вместо того, чтобы зависеть от потока управления статически связанными объектами, поток зависит от общего графа объекта и отношений между различными объектами.

Внедрение зависимостей - это шаблон проектирования, который реализует принцип IoC для разрешения зависимостей объектов.

Проще говоря, когда вы пытаетесь написать код, вы будете создавать и использовать разные классы. Один класс (класс A) может использовать другие классы (класс B и / или D). Итак, классы B и D являются зависимостями класса A.

Простая аналогия - автомобиль класса. Автомобиль может зависеть от других классов, таких как двигатель, шины и др.

Внедрение зависимостей предполагает, что вместо зависимых классов (здесь Class Car), создающих свои зависимости (Class Engine и класс Tire), класс должен быть внедрен с конкретным экземпляром зависимости.

Давайте разберемся с более практическим примером. Учтите, что вы пишете свой собственный TextEditor. Помимо прочего, у вас может быть программа для проверки орфографии, которая предоставляет пользователю возможность проверять опечатки в его тексте. Простая реализация такого кода может быть:

Class TextEditor
{

    //Lot of rocket science to create the Editor goes here

    EnglishSpellChecker objSpellCheck;
    String text;

    public void TextEditor()

    {   

        objSpellCheck = new EnglishSpellChecker();

    }

    public ArrayList <typos> CheckSpellings()
    {

        //return Typos;

    }

}

На первый взгляд все выглядит радужно. Пользователь напишет текст. Разработчик захватит текст и вызовет функцию CheckSpellings и найдет список опечаток, который он покажет пользователю.

Кажется, все работает отлично, пока в один прекрасный день один пользователь не начинает писать в редакторе по-французски.

Чтобы обеспечить поддержку большего количества языков, нам нужно больше SpellCheckers. Наверное, французский, немецкий, испанский и т. Д.

Здесь мы создали тесно связанный код с «английским» SpellChecker, тесно связанным с нашим классом TextEditor, что означает, что наш класс TextEditor зависит от EnglishSpellChecker или, другими словами, EnglishSpellCheker является зависимостью для TextEditor. Нам нужно удалить эту зависимость. Кроме того, нашему текстовому редактору необходим способ хранения конкретной ссылки на любую программу проверки орфографии на усмотрение разработчика во время выполнения.

Итак, как мы видели во введении DI, он предполагает, что в класс следует внедрить его зависимости. Таким образом, вызывающий код должен быть обязан внедрить все зависимости в вызываемый класс / код. Итак, мы можем реструктурировать наш код как

interface ISpellChecker
{

    Arraylist<typos> CheckSpelling(string Text);

}

Class EnglishSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}



Class FrenchSpellChecker : ISpellChecker

{

    public override Arraylist<typos> CheckSpelling(string Text)

    {

        //All Magic goes here.

    }

}

В нашем примере класс TextEditor должен получить конкретный экземпляр типа ISpellChecker.

Теперь зависимость можно внедрить в конструктор, публичное свойство или метод.

Попробуем изменить наш класс с помощью Constructor DI. Измененный класс TextEditor будет выглядеть примерно так:

Class TextEditor

{

    ISpellChecker objSpellChecker;

    string Text;



    public void TextEditor(ISpellChecker objSC)

    {

        objSpellChecker = objSC;

    }



    public ArrayList <typos> CheckSpellings()

    {

        return objSpellChecker.CheckSpelling();

    }

}

Чтобы вызывающий код при создании текстового редактора мог внедрить соответствующий тип SpellChecker в экземпляр TextEditor.

Вы можете прочитать полную статью здесь

person Amrit    schedule 16.07.2018

IOC - это техника, при которой вы позволяете кому-то другому создать объект за вас. И еще кто-то в случае весны - это контейнер IOC.

Инъекция зависимостей - это метод, при котором один объект обеспечивает зависимость другого объекта.

person daemon    schedule 28.07.2019

IOC означает инверсию управления и представляет собой концепцию более высокого уровня, которая гласит, что мы инвертируем управление созданием объектов от вызывающего к вызываемому.

Без инверсии управления вы отвечаете за создание объектов. В сценарии инверсии управления за создание экземпляров класса отвечает структура.

Внедрение зависимостей - это метод, с помощью которого мы можем добиться инверсии управления. Для того, чтобы мы оставили контроль за фреймворком или заданием, мы объявляем зависимости, и контейнер IOC внедряет эти зависимости в наш класс (т.е. фреймворк создает для нас экземпляр и предоставляет его нашему классу).

Каковы преимущества этого?

В первую очередь классы и их жизненный цикл будет управляться Spring. Spring полностью управляет процессом от создания до разрушения.

Во-вторых, вы уменьшите связь между классами. Класс не тесно связан с реализацией другого класса. Если реализация изменяется или если вы хотите изменить реализацию внедренного интерфейса, вы можете сделать это легко, не изменяя вручную все экземпляры в базе кода.

В-третьих, между классами усиливается сплоченность. Высокая сплоченность означает, что классы, которые связаны друг с другом, вместе. Поскольку мы внедряем интерфейсы в другие классы, ясно, какие классы необходимы для работы вызывающего класса.

В-четвертых, повышенная проверяемость. Поскольку мы используем интерфейсы в конструкторе, мы можем легко заменить реализацию на фиктивную реализацию.

в-пятых, использование динамического прокси JDK для прокси-объектов. динамический прокси JDK требует использования интерфейсов, что верно, потому что мы внедряем эти интерфейсы. Затем этот прокси-сервер можно использовать для Spring AOP, обработки транзакций, данных Spring, безопасности Spring и т. Д.

person Daniel Jacob    schedule 25.08.2020

Проще говоря ..

  • IOC (Inversion of Control) - это концепция, которая означает: вместо создания объектов с помощью оператора new позвольте контейнеру сделать это за вас.
  • DI (внедрение зависимостей) - это способ внедрения зависимости компонента фреймворка следующими способами Spring:
  1. Контракторный впрыск
  2. Инъекция сеттера / геттера
  3. полевая закачка
person NeeruKSingh    schedule 24.08.2020

Традиционным способом получения экземпляра адреса в Employee было бы создание нового экземпляра класса Address. Spring создает все зависимые объекты, поэтому нам не нужно беспокоиться об объекте.

Итак, в Spring мы просто зависим от контейнера Spring, который предоставляет нам объект зависимости.

person SumataPatil    schedule 23.01.2017