Spring Frameworkの依存性注入と制御の反転とは何ですか?


111

「依存性注入」と「制御の反転」は、Webフレームワークを開発するためにSpringフレームワークを使用する主な利点としてよく言及されます。

誰かがそれが何であるかを可能であれば例を用いて非常に簡単な言葉で説明できますか?



3
@SteveChambersは重複していません。この質問はSprings Perspectiveで行われます。その質問は一般に前向きです。
VdeX 2015年

回答:


233
  • 依存性注入のため、Springは疎結合アプリケーションの作成に役立ちます。
  • Springでは、オブジェクトが関連(依存関係)を定義し、オブジェクトがそれらの依存関係をどのように取得するかについては心配しません。オブジェクトの作成に必要な依存関係を提供するのは、Springの責任です。

:オブジェクトがEmployeeあり、オブジェクトに依存しているとしますAddressEmployeeオブジェクトへの依存関係を定義するBean を定義しますAddress

SpringがEmployeeオブジェクトを作成しようとすると、Employeeがに依存していることがわかるAddressため、まずAddressオブジェクト(依存オブジェクト)を作成してから、それをEmployeeオブジェクトに挿入します。

  • 制御の反転(IoC)と依存性注入(DI)は同じ意味で使用されます。IoCはDIを通じて実現されます。DIは依存関係を提供するプロセスであり、IoCはDIの最終結果です。(注: IoCを実現する方法はDIだけではありません。他の方法もあります。)

  • DIによって、オブジェクトを作成する責任は、アプリケーションコードからSpringコンテナーに移されます。この現象はIoCと呼ばれます。

  • 依存性注入は、セッター注入またはコンストラクター注入によって実行できます。

同意しません。これは明確な説明ではないと思います。フレームワークを作成して挿入するのではなく、「従業員」内で「アドレス」をインスタンス化できないのはなぜですか?もう少し詳細な例が必要です。
ボリス

2
@Boris誰も自分のオブジェクトをインスタンス化することはできないと言った。しかし、答えの唯一の目的は、DIで同じことを実現する方法を示すことでした。クライアントコードによってインスタンス化されたDIとオブジェクトの両方を持つことができます。これは、少なくとも部分的にはまだIOCと呼ばれます。
bogdan.rusu


ボリス。大変うらめしい?それがこれまでで最高の答えです。
Aniket Kapse

31

私はこの二つの用語の理解私のシンプルを書き留めなければならない(迅速な理解のためだけの例を読んで)

  • 依存性注入(DI):
    依存性注入とは通常、メソッドに依存オブジェクトを作成させるのではなく、依存オブジェクトをパラメーターとしてメソッドに渡すこと意味します
    実際にそれが意味することは、メソッドが特定の実装に直接依存しないことです。要件を満たす任意の実装をパラメーターとして渡すことができます。

    このオブジェクトの実装により、依存関係が定義されます。そして春はそれを利用できるようにします。
    これは、疎結合のアプリケーション開発につながります。

    簡単な例:EMPLOYEE OBJECT WHEN CREATED、IT WALL CREATE ADDRESS OBJECT(if address is defined as dependency as Employee object)*。

  • 制御の反転(IoC)コンテナー:
    これはフレームワークの一般的な特性であり、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

    制御の反転を実装することにより、ソフトウェア/オブジェクトの消費者は、制御されたりオプションが少なくなったりする代わりに、ソフトウェア/オブジェクトよりも多くの制御/オプションを取得します。

    設計ガイドラインとしての制御の反転は、次の目的に役立ちます
    。-特定のタスクの実行と実装の分離があります。
    -すべてのモジュールは、その設計目的に焦点を合わせることができます。
    -モジュールは他のシステムが何をするかについての仮定を行わず、契約に依存します。
    -モジュールを交換しても他のモジュールに影響はありません

ここでは抽象的にします。トピックの詳細を理解するには、次のリンクにアクセスしてください。

例を読む

詳細説明


11

Springオブジェクトは疎結合です。つまり、すべてのクラスを個別にテストできるように、各クラスは互いに独立しています。ただし、これらのクラスを使用する場合、クラスは最初にインスタンス化する必要がある他のクラスに依存している場合があります。

したがって、クラスAがクラスBに依存していることをスプリングに伝えます。したがって、クラスAのBean(クラスのような)を作成する場合、クラスAの前にクラスBをインスタンス化し、セッターまたはコンストラクターDIメソッドを使用してクラスAにそれを注入します。つまり、実行時に依存関係をSpringに通知しています。これはDIです。

オブジェクト(Bean)を作成し、それらとその集約を保守する責任を、ハードコーディングする代わりにSpringに割り当てているため、Inversion Of Control(IOC)と呼んでいます。


7

制御の反転(IOC):

IoCは、システム内の制御フローの反転を記述する設計パターンであるため、実行フローは中央のコードによって制御されません。これは、コンポーネントが他のコンポーネントの抽象化のみに依存する必要があり、依存オブジェクトの作成を処理する責任がないことを意味します。代わりに、オブジェクトインスタンスは、実行時にDependency Injection(DI)を介してIoCコンテナーによって提供されます。

IoCは、ソフトウェアコンポーネントの再利用、疎結合、および簡単なテストを容易にする優れたソフトウェア設計を可能にします。

依存性注入(DI):

DIは、依存関係をオブジェクトのコンストラクターに渡すための手法です。オブジェクトがコンテナからロードされている場合、その依存関係はコンテナによって自動的に提供されます。これにより、インスタンスを手動で作成しなくても、依存関係を利用できます。これにより、結合が減少し、オブジェクトインスタンスのライフタイムをより詳細に制御できます。

クリックしてもっと見る


6

Spring:Springは、Javaプラットフォームの「制御の反転」コンテナです。

制御の反転(IoC):制御の反転(IoC)は、オブジェクト指向のプログラミング手法であり、オブジェクト結合は実行時に「アセンブラー」オブジェクトによって制限され、通常、静的分析を使用したコンパイル時にはわかりません。

依存性注入(DI):「依存性注入は、ハードコードされた依存関係を削除できるソフトウェア設計パターンであり、実行時でもコンパイル時でも、それらを変更できます。」-wiki。


これは、すでに存在するもの(この回答のソースとなる場所)よりも簡単なのでしょうか。用語を囲む二重引用符で魔法のように単純化しない限り、OPの単純化の要求は考慮されていません。
ウドゥンの炎

6

制御の反転-これは、Spring Beanを作成してインスタンス化する制御をSpring IOCコンテナーに与えることを意味し、開発者が行う唯一の作業は、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";

  }
}

上記のコードでは、Addressクラスの値は、EmployeeクラスがAddressクラスの依存関係であるEmployeeクラスがインスタンス化されたときにのみ設定されます。そして、Springはこの依存性を注入する2つの方法を提供することにより、依存性注入の概念を使用してこの問題を解決します。

  1. セッター注入

Addressクラスの参照を受け取るEmployeeクラスのSetterメソッド

public void setAddress(Address addr) {
    this.address = addr;
}
  1. コンストラクター注入

Addressを受け入れるEmployeeクラスのコンストラクタ

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

このように、アドレスクラスの値は、セッター/コンストラクターの注入を使用して個別に設定できます。


3

制御の反転は、保守が容易な再利用可能なモジュール式ソフトウェアフレームワークの作成を支援するソフトウェアアーキテクチャの一般的な設計原則です。

これは、フローの制御がジェネリックで作成されたライブラリまたは再利用可能なコードから「受信」される設計原則です。

それをよりよく理解するために、コーディングの初期の頃のコーディング方法を見てみましょう。手続き型/従来型言語では、ビジネスロジックは通常、アプリケーションのフローを制御し、汎用または再利用可能なコード/関数を「呼び出し」ます。たとえば、単純なコンソールアプリケーションでは、制御フローはプログラムの命令によって制御されます。これには、いくつかの一般的な再利用可能な関数の呼び出しが含まれる場合があります。

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要素を作成するためのフレームワークがすでに利用できます。アプリケーションのビジネスロジックを記述する場合、ビジネスロジックコードを呼び出すのはフレームワークのイベントであり(イベントが発生したとき)、その逆ではありません。

フレームワークのコードは私のビジネスロジックを認識していませんが、コードを呼び出す方法は認識しています。これは、イベント/デリゲート、コールバックなどを使用して実現されます。ここでは、フローの制御が「反転」されています。

したがって、静的にバインドされたオブジェクトの制御フローに依存する代わりに、フローはオブジェクトグラフ全体と異なるオブジェクト間の関係に依存します。

Dependency Injectionは、オブジェクトの依存関係を解決するためのIoC原則を実装する設計パターンです。

簡単に言うと、コードを記述しようとしているときは、さまざまなクラスを作成して使用することになります。1つのクラス(クラスA)は、他のクラス(クラスBまたはD、あるいはその両方)を使用できます。したがって、クラスBおよびDはクラスAの依存関係です。

簡単な例えはクラスカーです。車は、エンジン、タイヤなどの他のクラスに依存している場合があります。

Dependency Injectionは、Dependentクラス(ここではClass Car)が依存関係(Class EngineおよびクラスTyre)を作成する代わりに、クラスに依存関係の具象インスタンスを注入する必要があることを示唆しています。

より実用的な例で理解しましょう。独自の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が必要です。おそらくフランス語、ドイツ語、スペイン語など。

ここでは、 "English" 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タイプの具象インスタンスを受け取る必要があります。

これで、コンストラクター、パブリックプロパティ、またはメソッドに依存関係を注入できます。

コンストラクターDIを使用してクラスを変更してみましょう。変更されたTextEditorクラスは次のようになります。

Class TextEditor

{

    ISpellChecker objSpellChecker;

    string Text;



    public void TextEditor(ISpellChecker objSC)

    {

        objSpellChecker = objSC;

    }



    public ArrayList <typos> CheckSpellings()

    {

        return objSpellChecker.CheckSpelling();

    }

}

そのため、呼び出しコードは、テキストエディターの作成中に、適切なSpellChecker TypeをTextEditorのインスタンスに注入できます。

ここで完全な記事を読むことができます


1

Employeeで住所インスタンスを取得する従来の方法は、Addressクラスの新しいインスタンスを作成することです。Springはすべての依存オブジェクトを作成するため、オブジェクトについて心配する必要はありません。

したがって、Springでは、依存関係オブジェクトを提供するSpringコンテナに依存しています。


1

IOCは、他の人にオブジェクトを作成させる方法です。そして、春の場合の誰かはIOCコンテナです。

依存性注入は、あるオブジェクトが別のオブジェクトの依存性を提供する手法です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.