Spring Framework에서 종속성 주입 및 제어 반전이란 무엇입니까?
"종속성 주입"과 "제어의 반전"은 웹 프레임 워크 개발에 Spring 프레임 워크를 사용하는 주요 이점으로 자주 언급됩니다.
가능한 한 예를 들어 매우 간단한 용어로 설명 할 수 있습니까?
- 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 주입 또는 생성자 주입으로 수행 할 수 있습니다.
이 두 용어에 대한 간단한 이해를 적어 보겠습니다.
For quick understanding just read examples*
종속성 주입 (DI) :
종속성 주입은 일반적으로 메서드가 종속 객체를 생성하도록하는 대신 종속 객체를 매개 변수로 메서드에 전달하는 것을 의미 합니다 .
실제로 의미하는 바는 메서드가 특정 구현에 직접 의존하지 않는다는 것입니다. 요구 사항을 충족하는 모든 구현은 매개 변수로 전달 될 수 있습니다.
이러한 개체 구현으로 종속성을 정의합니다. 그리고 봄은 그것을 가능하게합니다.
이는 느슨하게 결합 된 애플리케이션 개발로 이어집니다.
Quick Example:EMPLOYEE OBJECT WHEN CREATED,IT WILL AUTOMATICALLY CREATE ADDRESS OBJECT (if address is defines as dependency by Employee object)*.<br>
IoC (Inversion of Control) 컨테이너 :
이것은 프레임 워크의 일반적인 특성이며, 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 클래스의 종속성입니다. 스프링은 의존성 주입 개념을 사용하여이 의존성을 주입하는 두 가지 방법을 제공함으로써이 문제를 해결합니다.
- 세터 주입
Setter method in Employee class which takes a reference of Address class
public void setAddress(Address addr) {
this.address = addr;
}
- Constructor injection
Constructor in Employee class which accepts Address
Employee(Address addr) {
this.address = addr;
}
In this way the Address class values can be set independently using either setter/constructor injection.
Inversion of Control is a generic design principle of software architecture that assists in creating reusable, modular software frameworks that are easy to maintain.
It is a design principle in which the Flow of Control is "received" from the generic-written library or reusable code.
To understand it better, lets see how we used to code in our earlier days of coding. In procedural/traditional languages, the business logic generally controls the flow of the application and "Calls" the generic or reusable code/functions. For example, in a simple Console application, my flow of control is controlled by my program's instructions, that may include the calls to some general reusable functions.
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
In Contrast, with IoC, the Frameworks are the reusable code that "Calls" the business logic.
For example, in a windows based system, a framework will already be available to create UI elements like buttons, menus, windows and dialog boxes. When I write the business logic of my application, it would be framework's events that will call my business logic code (when an event is fired) and NOT the opposite.
Although, the framework's code is not aware of my business logic, it will still know how to call my code. This is achieved using events/delegates, callbacks etc. Here the Control of flow is "Inverted".
So, instead of depending the flow of control on statically bound objects, the flow depends upon the overall object graph and the relations between different objects.
Dependency Injection is a design pattern that implements IoC principle for resolving dependencies of objects.
In simpler words, when you are trying to write code, you will be creating and using different classes. One class (Class A) may use other classes (Class B and/or D). So, Class B and D are dependencies of class A.
A simple analogy will be a class Car. A car might depend on other classes like Engine, Tyres and more.
Dependency Injection suggests that instead of the Dependent classes (Class Car here) creating its dependencies (Class Engine and class Tyre), class should be injected with the concrete instance of the dependency.
Lets understand with a more practical example. Consider that you are writing your own TextEditor. Among other things, you can have a spellchecker that provides the user with a facility to check the typos in his text. A simple implementation of such a code can be:
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;
}
}
At first sight, all looks rosy. The user will write some text. The developer will capture the text and call the CheckSpellings function and will find a list of Typos that he will show to the User.
Everything seems to work great until one fine day when one user starts writing French in the Editor.
To provide the support for more languages, we need to have more SpellCheckers. Probably French, German, Spanish etc.
Here, we have created a tightly-coupled code with "English"SpellChecker being tightly coupled with our TextEditor class, which means our TextEditor class is dependent on the EnglishSpellChecker or in other words EnglishSpellCheker is the dependency for TextEditor. We need to remove this dependency. Further, Our Text Editor needs a way to hold the concrete reference of any Spell Checker based on developer's discretion at run time.
So, as we saw in the introduction of DI, it suggests that the class should be injected with its dependencies. So, it should be the calling code's responsibility to inject all the dependencies to the called class/code. So we can restructure our code as
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.
}
}
In our example, the TextEditor class should receive the concrete instance of ISpellChecker type.
Now, the dependency can be injected in Constructor, a Public Property or a method.
Lets try to change our class using Constructor DI. The changed TextEditor class will look something like:
Class TextEditor
{
ISpellChecker objSpellChecker;
string Text;
public void TextEditor(ISpellChecker objSC)
{
objSpellChecker = objSC;
}
public ArrayList <typos> CheckSpellings()
{
return objSpellChecker.CheckSpelling();
}
}
So that the calling code, while creating the text editor can inject the appropriate SpellChecker Type to the instance of the TextEditor.
You can read the complete article here
The traditional way of getting address instance in Employee would be by creating a new instance of Address class.Spring creates all dependent object ton us hence we need not to worry about object.
So in Spring we just depend on the spring container which provide us with the dependency object.
IOC is technique where you let someone else to create the object for you. And the someone else in case of spring is IOC container.
Dependency Injection is a technique where one object supplies the dependency of another object.
'programing' 카테고리의 다른 글
부울 연산자의 차이점 : & 대 && 및 | (0) | 2020.08.17 |
---|---|
PHP 날짜를 포함하는 요소로 다차원 배열 정렬 (0) | 2020.08.17 |
쉘에서 Erlang의 릴리스 버전 번호를 얻는 방법은 무엇입니까? (0) | 2020.08.17 |
OpenShift와 함께 기존 git repo를 사용할 수 있습니까? (0) | 2020.08.17 |
Gson을 사용하여 JSON 배열을 java.util.List로 구문 분석 (0) | 2020.08.17 |