Spring Framework에서 종속성 주입 및 제어 반전이란 무엇입니까?


111

"종속성 주입"과 "제어의 반전"은 웹 프레임 워크 개발을위한 Spring 프레임 워크 사용의 주요 이점으로 자주 언급됩니다.

가능한 한 예를 들어 매우 간단한 용어로 설명 할 수 있습니까?



3
@SteveChambers는 중복되지 않으며이 질문은 Springs Perspective에서 요청됩니다. 그 질문은 일반적으로 전향 적입니다.
VdeX 2015 년

답변:


233
  • Spring은 Dependency Injection으로 인해 느슨하게 결합 된 애플리케이션을 만드는 데 도움이됩니다 .
  • Spring에서 객체는 연관 (종속성)을 정의하고 이러한 종속성 을 얻는 방법에 대해 걱정하지 않습니다 . 객체 생성에 필요한 종속성을 제공하는 것은 Spring의 책임입니다.

예를 들면 다음 Employee과 같습니다. 객체가 있고 객체에 대한 종속성이 있다고 가정 합니다 Address. Employee객체에 대한 종속성을 정의 할에 해당하는 빈 을 정의합니다 Address.

Spring이 Employee객체 를 생성하려고 할 때 , 그것은 Employee의존성이있는 것을 볼 것이다 Address. 그래서 그것은 먼저 Address객체 (종속 객체)를 생성 한 다음 객체에 주입 할 Employee것이다.

  • IoC (Inversion of Control )와 DI (Dependency Injection )는 서로 바꿔서 사용할 수 있습니다. IoC는 DI를 통해 달성됩니다. DI는 종속성을 제공하는 프로세스이며 IoC는 DI의 최종 결과입니다. ( 참고 : DI는 IoC를 달성하는 유일한 방법이 아닙니다. 다른 방법 도 있습니다.)

  • DI에 의해 객체 생성 책임은 우리의 애플리케이션 코드에서 Spring 컨테이너로 옮겨졌습니다. 이 현상을 IoC라고합니다.

  • 의존성 주입은 setter 주입 또는 생성자 주입으로 수행 할 수 있습니다.

동의하지 않습니다. 나는 이것이 명확한 설명이라고 생각하지 않습니다. 프레임 워크를 생성하여 주입하는 대신 "Employee"내에서 "Address"를 인스턴스화 할 수없는 이유는 무엇입니까? 약간 더 자세한 예제가 필요합니다.
Boris

2
@Boris 아무도 자신의 개체를 인스턴스화 할 수 없다고 말하지 않았습니다. 그러나 대답의 유일한 목적은 DI로 어떻게 동일한 결과를 얻을 수 있는지 보여주는 것이 었습니다. 클라이언트 코드에 의해 인스턴스화 된 DI와 객체를 모두 가질 수 있습니다. 이것은 적어도 부분적으로는 여전히 IOC라고 불릴 것입니다.
bogdan.rusu


보리스. 많이 질투? 그게 최고의 대답입니다.
Aniket Kapse

31

이 두 용어에 대한 간단한 이해를 적어 보겠습니다. (빠른 이해를 위해 예제를 읽으십시오)

  • 종속성 주입 (DI) :
    종속성 주입은 일반적으로 메서드가 종속 객체를 생성하도록하는 대신 종속 객체를 매개 변수로 메서드에 전달하는 것을 의미 합니다 .
    실제로 의미하는 바는 메서드가 특정 구현에 직접 의존하지 않는다는 것입니다. 요구 사항을 충족하는 모든 구현은 매개 변수로 전달 될 수 있습니다.

    이러한 개체 구현으로 종속성을 정의합니다. 그리고 봄은 그것을 가능하게합니다.
    이는 느슨하게 결합 된 애플리케이션 개발로 이어집니다.

    빠른 예 : EMPLOYEE OBJECT WHEN CREATED, IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT (if address is defined as dependency by Employee object) *.

  • Inversion of Control (IoC) Container :
    이것은 프레임 워크의 일반적인 특성으로, IoC
    인스턴스화에서 BeanFactory를 통한 파괴에 이르기까지 Java 객체를 관리합니다 .
    -IoC 컨테이너에 의해 인스턴스화 된 Java 구성 요소를 Bean이라고하며 IoC 컨테이너는 Bean의 범위, 수명주기 이벤트 및 구성 및 코딩 된 모든 AOP 기능관리합니다 .

    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.

    Inversion of Control을 구현함으로써 소프트웨어 / 객체 소비자는 제어되거나 더 적은 옵션을 갖는 대신 소프트웨어 / 객체에 대해 더 많은 제어 / 옵션을 얻습니다.

    설계 지침으로서의 제어 역전은 다음과 같은 목적으로 사용됩니다
    .-구현에서 특정 작업 실행의 분리가 있습니다.
    -모든 모듈은 설계 대상에 집중할 수 있습니다.
    -모듈은 다른 시스템이하는 일에 대해 가정하지 않고 계약에 의존합니다.
    -모듈 교체는 다른 모듈에 부작용이 없습니다.

여기서는 추상적 인 내용을 유지하겠습니다. 주제에 대한 자세한 이해를 위해 다음 링크를 방문 할 수 있습니다.

예를 들어 좋은 읽기

상해


11

Spring Objects는 느슨하게 결합되어 있습니다. 즉, 각 클래스는 서로 독립적이므로 모든 것이 개별적으로 테스트 될 수 있습니다. 그러나 이러한 클래스를 사용할 때 클래스는 먼저 인스턴스화해야하는 다른 클래스에 종속 될 수 있습니다.

그래서 우리는 클래스 A가 클래스 B에 의존한다고 스프링에게 알려줍니다. 그래서 클래스 A에 대한 빈 (클래스와 같은)을 만들 때 클래스 A보다 먼저 클래스 B를 인스턴스화하고 setter 또는 생성자 DI 메서드를 사용하여 클래스 A에 주입합니다. 즉, 우리는 런타임에 의존성을 봄에 말하고 있습니다. DI입니다.

우리는 객체 (빈)를 생성하고 그것들과 그 집합을 하드 코딩하는 대신 Spring에 유지하는 책임을 할당하고 있기 때문에이를 Inversion Of Control (IOC)이라고 부릅니다.


7

IOC (Inversion Of Control) :

IoC 는 시스템에서 제어 흐름을 반전시키는 것을 설명하는 디자인 패턴이므로 실행 흐름은 중앙 코드에 의해 제어되지 않습니다. 즉, 구성 요소는 다른 구성 요소의 추상화에만 의존해야하며 종속 개체의 생성을 처리 할 책임이 없습니다. 대신 개체 인스턴스는 DI (Dependency Injection)를 통해 IoC 컨테이너에서 런타임에 제공됩니다.

IoC는 재사용, 느슨한 결합 및 소프트웨어 구성 요소의 쉬운 테스트를 용이하게하는 더 나은 소프트웨어 설계를 가능하게합니다.

DI (종속성 주입) :

DI 는 종속성을 객체의 생성자에 전달하는 기술입니다. 개체가 컨테이너에서로드 된 경우 해당 종속성은 컨테이너에서 자동으로 제공됩니다. 이를 통해 인스턴스를 수동으로 생성하지 않고도 종속성을 사용할 수 있습니다. 이렇게하면 결합이 줄어들고 개체 인스턴스의 수명을 더 잘 제어 할 수 있습니다.

더 보려면 클릭하세요


6

Spring : Spring은 Java 플랫폼을위한 "Inversion of Control"컨테이너입니다.

IoC (Inversion of Control) : Inversion of Control (IoC)은 객체 결합이 런타임시 "어셈블러"객체에 의해 제한되고 일반적으로 정적 분석을 사용하여 컴파일 타임에 알 수없는 객체 지향 프로그래밍 방식입니다.

DI (Dependency Injection) : "Dependency injection은 하드 코딩 된 종속성을 제거하고 런타임 또는 컴파일 시간에이를 변경할 수 있도록하는 소프트웨어 디자인 패턴입니다." -위키.


이미 존재하는 것 (이 답변의 출처)보다 이것이 어떻게 더 간단합니까? 용어 주위의 큰 따옴표가 마술처럼 일을 더 간단하게 만들지 않는 한 단순성에 대한 OP의 요청을 설명하지 않습니다.
우둔의 불꽃

6

Inversion of control- Spring IOC 컨테이너에 Spring Bean을 생성하고 인스턴스화하는 제어를 제공하는 것을 의미하며 개발자가 수행하는 유일한 작업은 Spring xml 파일에서 Bean을 구성하는 것입니다.

의존성 주입

클래스 직원 고려

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

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


}

클래스 주소 고려

class Address {
   private String street;
   private String city;

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

  }
}

위 코드에서 주소 클래스 값은 Employee 클래스가 인스턴스화 될 때만 설정되며 이는 Employee 클래스에 대한 Address 클래스의 종속성입니다. 그리고 Spring은이 의존성을 주입하는 두 가지 방법을 제공함으로써 Dependency Injection 개념을 사용하여이 문제를 해결합니다.

  1. 세터 주입

Address 클래스를 참조하는 Employee 클래스의 Setter 메서드

public void setAddress(Address addr) {
    this.address = addr;
}
  1. 생성자 주입

주소를 허용하는 Employee 클래스의 생성자

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

이런 식으로 Address 클래스 값은 setter / constructor injection을 사용하여 독립적으로 설정할 수 있습니다.


3

Inversion of Control은 유지 관리가 쉬운 재사용 가능한 모듈 식 소프트웨어 프레임 워크를 만드는 데 도움이되는 소프트웨어 아키텍처의 일반적인 설계 원칙입니다.

제어 흐름이 일반 작성 라이브러리 또는 재사용 가능한 코드에서 "수신"되는 디자인 원칙입니다.

더 잘 이해하기 위해 우리가 코딩 초기에 어떻게 코딩했는지 살펴 보겠습니다. 절차 적 / 전통적인 언어에서 비즈니스 로직은 일반적으로 애플리케이션의 흐름을 제어하고 일반 또는 재사용 가능한 코드 / 함수를 "호출"합니다. 예를 들어, 간단한 콘솔 애플리케이션에서 제어 흐름은 일부 일반 재사용 가능 함수에 대한 호출을 포함 할 수있는 프로그램의 지침에 의해 제어됩니다.

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에서 프레임 워크는 비즈니스 로직을 "호출"하는 재사용 가능한 코드입니다.

예를 들어 Windows 기반 시스템에서 프레임 워크는 버튼, 메뉴, 창 및 대화 상자와 같은 UI 요소를 만드는 데 이미 사용할 수 있습니다. 내 애플리케이션의 비즈니스 로직을 작성할 때, 내 비즈니스 로직 코드 (이벤트가 시작될 때)를 호출하는 것은 프레임 워크의 이벤트가되고 그 반대가 아닙니다.

프레임 워크의 코드는 내 비즈니스 로직을 인식하지 못하지만 여전히 내 코드를 호출하는 방법을 알고 있습니다. 이는 이벤트 / 대리자, 콜백 등을 사용하여 수행됩니다. 여기서 흐름 제어는 "반전"됩니다.

따라서 정적으로 바인딩 된 개체의 제어 흐름에 의존하는 대신 흐름은 전체 개체 그래프와 서로 다른 개체 간의 관계에 따라 달라집니다.

의존성 주입은 객체의 의존성을 해결하기위한 IoC 원칙을 구현하는 디자인 패턴입니다.

간단히 말해서 코드를 작성하려고 할 때 다른 클래스를 만들고 사용하게됩니다. 한 클래스 (클래스 A)는 다른 클래스 (클래스 B 및 / 또는 D)를 사용할 수 있습니다. 따라서 클래스 B와 D는 클래스 A의 종속성입니다.

간단한 비유는 Car 클래스입니다. 자동차는 엔진, 타이어 등과 같은 다른 클래스에 의존 할 수 있습니다.

종속성 주입은 종속성 (Class Engine 및 클래스 Tyre)을 만드는 Dependent 클래스 (여기서는 Class Car) 대신 종속성의 구체적인 인스턴스와 함께 클래스를 주입해야합니다.

보다 실용적인 예를 들어 이해하겠습니다. 자신 만의 텍스트 편집기를 작성하고 있다고 생각해보십시오. 무엇보다도 사용자에게 텍스트의 오타를 검사하는 기능을 제공하는 맞춤법 검사기를 사용할 수 있습니다. 이러한 코드의 간단한 구현은 다음과 같습니다.

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 함수를 호출하고 사용자에게 표시 할 오타 목록을 찾습니다.

한 사용자가 편집기에서 프랑스어를 쓰기 시작하는 어느 화창한 날까지 모든 것이 잘 작동하는 것 같습니다.

더 많은 언어에 대한 지원을 제공하려면 더 많은 SpellChecker가 필요합니다. 아마도 프랑스어, 독일어, 스페인어 등일 것입니다.

여기에서 우리는 TextEditor 클래스와 밀접하게 결합 된 "English"SpellChecker를 사용하여 밀접하게 결합 된 코드를 만들었습니다. 이는 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 인스턴스에 삽입 할 수 있습니다.

여기 에서 전체 기사를 읽을 수 있습니다.


1

Employee에서 주소 인스턴스를 가져 오는 전통적인 방법은 Address 클래스의 새 인스턴스를 만드는 것입니다 .Spring은 모든 종속 개체를 생성하므로 개체에 대해 걱정할 필요가 없습니다.

그래서 Spring에서 우리는 의존성 객체를 제공하는 스프링 컨테이너에 의존합니다.


1

IOC는 다른 사람이 당신을 위해 객체를 생성하도록하는 기술입니다. 그리고 봄의 경우 다른 사람은 IOC 컨테이너입니다.

종속성 주입은 한 개체가 다른 개체의 종속성을 제공하는 기술입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.