"종속성 주입"과 "제어의 반전"은 웹 프레임 워크 개발을위한 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라고합니다.
이 두 용어에 대한 간단한 이해를 적어 보겠습니다. (빠른 이해를 위해 예제를 읽으십시오)
종속성 주입 (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을 구현함으로써 소프트웨어 / 객체 소비자는 제어되거나 더 적은 옵션을 갖는 대신 소프트웨어 / 객체에 대해 더 많은 제어 / 옵션을 얻습니다.
설계 지침으로서의 제어 역전은 다음과 같은 목적으로 사용됩니다
.-구현에서 특정 작업 실행의 분리가 있습니다.
-모든 모듈은 설계 대상에 집중할 수 있습니다.
-모듈은 다른 시스템이하는 일에 대해 가정하지 않고 계약에 의존합니다.
-모듈 교체는 다른 모듈에 부작용이 없습니다.
여기서는 추상적 인 내용을 유지하겠습니다. 주제에 대한 자세한 이해를 위해 다음 링크를 방문 할 수 있습니다.
Spring Objects는 느슨하게 결합되어 있습니다. 즉, 각 클래스는 서로 독립적이므로 모든 것이 개별적으로 테스트 될 수 있습니다. 그러나 이러한 클래스를 사용할 때 클래스는 먼저 인스턴스화해야하는 다른 클래스에 종속 될 수 있습니다.
그래서 우리는 클래스 A가 클래스 B에 의존한다고 스프링에게 알려줍니다. 그래서 클래스 A에 대한 빈 (클래스와 같은)을 만들 때 클래스 A보다 먼저 클래스 B를 인스턴스화하고 setter 또는 생성자 DI 메서드를 사용하여 클래스 A에 주입합니다. 즉, 우리는 런타임에 의존성을 봄에 말하고 있습니다. DI입니다.
우리는 객체 (빈)를 생성하고 그것들과 그 집합을 하드 코딩하는 대신 Spring에 유지하는 책임을 할당하고 있기 때문에이를 Inversion Of Control (IOC)이라고 부릅니다.
IOC (Inversion Of Control) :
IoC 는 시스템에서 제어 흐름을 반전시키는 것을 설명하는 디자인 패턴이므로 실행 흐름은 중앙 코드에 의해 제어되지 않습니다. 즉, 구성 요소는 다른 구성 요소의 추상화에만 의존해야하며 종속 개체의 생성을 처리 할 책임이 없습니다. 대신 개체 인스턴스는 DI (Dependency Injection)를 통해 IoC 컨테이너에서 런타임에 제공됩니다.
IoC는 재사용, 느슨한 결합 및 소프트웨어 구성 요소의 쉬운 테스트를 용이하게하는 더 나은 소프트웨어 설계를 가능하게합니다.
DI (종속성 주입) :
DI 는 종속성을 객체의 생성자에 전달하는 기술입니다. 개체가 컨테이너에서로드 된 경우 해당 종속성은 컨테이너에서 자동으로 제공됩니다. 이를 통해 인스턴스를 수동으로 생성하지 않고도 종속성을 사용할 수 있습니다. 이렇게하면 결합이 줄어들고 개체 인스턴스의 수명을 더 잘 제어 할 수 있습니다.
Spring : Spring은 Java 플랫폼을위한 "Inversion of Control"컨테이너입니다.
IoC (Inversion of Control) : Inversion of Control (IoC)은 객체 결합이 런타임시 "어셈블러"객체에 의해 제한되고 일반적으로 정적 분석을 사용하여 컴파일 타임에 알 수없는 객체 지향 프로그래밍 방식입니다.
DI (Dependency Injection) : "Dependency injection은 하드 코딩 된 종속성을 제거하고 런타임 또는 컴파일 시간에이를 변경할 수 있도록하는 소프트웨어 디자인 패턴입니다." -위키.
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 개념을 사용하여이 문제를 해결합니다.
Address 클래스를 참조하는 Employee 클래스의 Setter 메서드
public void setAddress(Address addr) {
this.address = addr;
}
주소를 허용하는 Employee 클래스의 생성자
Employee(Address addr) {
this.address = addr;
}
이런 식으로 Address 클래스 값은 setter / constructor injection을 사용하여 독립적으로 설정할 수 있습니다.
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 인스턴스에 삽입 할 수 있습니다.
여기 에서 전체 기사를 읽을 수 있습니다.