Spring IoC (制御の反転)

IoC は Inversion of Control の略で、「制御の反転」と訳され、技術ではなく設計思想であり、オブジェクト指向プログラミングの重要なルールです。
Spring は、IoC コンテナを通じてすべての Java オブジェクトのインスタンス化と初期化を管理し、オブジェクト間の依存関係を制御します。IoC コンテナで管理される Java オブジェクトを Spring Bean と呼びますが、new キーワードを使用して作成される Java オブジェクトと区別はありません。IoC コンテナは Spring フレームワークの最も重要なコア コンポーネントの 1 つであり、Spring の誕生から成長までの全プロセスを実行します。

制御の反転 (IoC)

従来の Java アプリケーションでは、クラスが別のクラスのプロパティまたはメソッドを呼び出したい場合、通常、コード内の new Object() を通じて後者のオブジェクトを作成し、そのプロパティまたはメソッドを実装します。理解しやすく説明しやすいように、前者を「呼び出し元」、後者を「呼び出し先」と呼ぶことができます。言い換えれば、呼び出し元は呼び出し先オブジェクトの作成を制御できます。

ただし、Spring アプリケーションでは、Java オブジェクト作成の制御は IoC コンテナーにあり、一般的な手順は次のとおりです。

  1. 開発者は、XML 構成ファイル、アノテーション、Java 構成クラスなどを通じて Java オブジェクトを定義します。たとえば、XML 構成ファイルでの <bean> タグの使用、Java クラスでの @Component アノテーションの使用などです。
  2. Spring が開始すると、IOC コンテナはオブジェクト定義に基づいてこれらのオブジェクトを自動的に作成および管理します。IOC コンテナによって作成および管理されるこれらのオブジェクトは Spring Bean と呼ばれます。
  3. Bean を使用する場合は、コード (new Obejct() など) を介して手動で作成することなく、IOC コンテナから直接 (たとえば、ApplicationContext の getBean() メソッドを通じて) 取得できます。


IoCによってもたらされた最大の変化はコードレベルではなく、イデオロギーレベルでの「マスタースレーブ転置」の変化です。本来、呼び出し元はアクティブな当事者であり、主導権を握って、使用したいリソースを作成しますが、Spring アプリケーションでは、IoC コンテナーが主導権を保持し、呼び出し元は受動的当事者となり、受動的に IoC コンテナーを待ちます。 . 必要なオブジェクト (Bean) を作成します。

このプロセスには責任レベルでの制御の反転があり、実装を支援するコードを通じて呼び出し元によって最初に実装されたオブジェクトの作成を IoC コンテナーに逆転させるため、このプロセスを Spring の「制御の反転」と呼びます。

依存性注入 (DI)

IoC を理解した後は、依存性注入という別の非常に重要な概念も理解する必要があります。

依存性注入 (DI) は、2004 年に Martin Fowler が「制御の反転」を説明する際に提案しました。Martin Fowler は、「制御の反転」という用語が非常に曖昧で、人々が「どこで反転しているのか」を直接理解できないと考えているため、「制御の反転」の代わりに「依存性注入」を使用することを提案しました。

オブジェクト指向ではオブジェクト間に「依存関係」と呼ばれる関係があります。簡単に言えば、依存関係とは、あるオブジェクトが別のオブジェクトを使用する必要があること、つまり、オブジェクト内に属性があり、その属性が別のクラスのオブジェクトであることを意味します。

たとえば、次のコードを持つ B という名前の Java クラスがあります。 

public class B {
    String bid;
    A a;
}

コードからわかるように、B には型 A のオブジェクト属性 a が存在します。このとき、B のオブジェクトはオブジェクト a に依存していると言えます。依存関係の注入は、この「依存関係」に基づいています。

制御の反転の中心的な考え方は、Spring がオブジェクトの作成を担当するということです。オブジェクトの作成プロセス中に、Spring は依存関係に基づいて、依存するオブジェクトを現在のオブジェクトに自動的に挿入します (いわゆる「依存性注入」)。

IoCの仕組み

Java ソフトウェア開発プロセスでは、システム内のさまざまなオブジェクト間、さまざまなモジュール間、およびソフトウェア システムとハードウェア システム間に多かれ少なかれ結合関係があります。

システムの結合度が高すぎると、保守が困難な問題が発生しますが、結合度がまったくないコードでは、ほとんどすべての機能を完了するためにコード間​​の連携と相互依存が必要になるため、作業を完了することはほとんどできません。したがって、プログラムを設計する際には、システムの機能に影響を与えずに結合度を最大限に下げるという考え方が一般的です。

IoC の最下層では、ファクトリ モード、Java のリフレクション メカニズム、XML 解析などのテクノロジを使用して、コードの結合を最小限に抑えます。主な手順は次のとおりです。

  1. 構成ファイル (Bean.xml など) で、各オブジェクトとオブジェクト間の依存関係を構成します。
  2. IOC コンテナをファクトリーと考えることができ、このファクトリーの製品が Spring Bean です。
  3. コンテナーが起動すると、これらの構成ファイルが読み込まれて解析され、オブジェクトとオブジェクト間の依存関係に関する基本情報が取得されます。
  4. IOC は Java のリフレクション メカニズムを使用して、クラス名に基づいて対応するオブジェクト (つまり Spring Bean) を生成し、依存関係に基づいてこのオブジェクトをそれに依存するオブジェクトに注入します。

オブジェクトの基本情報とオブジェクト間の依存関係は構成ファイルで定義され、コード内で緊密に結合されていないため、オブジェクトが変更された場合でも、Java コードを変更することなく、構成ファイル内で変更するだけで済みます。これが Spring IOC デカップリングの原則です。

IoCコンテナの2つの実装

IoC のアイデアは IoC コンテナに基づいて実装されており、IoC コンテナの最下層は実際には Bean ファクトリです。Spring フレームワークは、BeanFactory と ApplicationContext という 2 つの異なるタイプの IoC コンテナを提供します。

ビーンファクトリー

BeanFactory は、IoC コンテナの基本的な実装であり、Spring によって提供される最も単純な IoC コンテナであり、IoC コンテナの最も基本的な機能を提供し、 org.springframework.beans.factory.BeanFactory インターフェースによって定義されます。

BeanFactory は遅延ロード機構を使用しており、コンテナは構成ファイルをロードするときにすぐに Java オブジェクトを作成せず、プログラム内でオブジェクトが取得 (使用) されたときにのみ作成されます。

例1

BeanFactory の使用。

HelloSpring プロジェクトで、BeanFactory を使用して HelloWorld オブジェクトを取得するように MainApp コードを変更します。具体的なコードは次のとおりです。 

public static void main(String[] args) {
    BeanFactory context = new ClassPathXmlApplicationContext("Beans.xml");
    HelloWorld obj = context.getBean("helloWorld", HelloWorld.class);
    obj.getMessage();
}

 2MainApp.java を実行すると、コンソール出力は次のようになります。

メッセージ : Hello World!

BeanFactory は Spring の内部インターフェイスであり、通常は開発者は利用できません。  

アプリケーションコンテキスト

ApplicationContext は、BeanFactory インターフェースのサブインターフェースであり、BeanFactory の拡張機能です。ApplicationContext は、AOP (アスペクト指向プログラミング)、国際化、トランザクション サポートなど、BeanFactory に基づいた多くのエンタープライズ レベルの機能を追加します。

ApplicationContext インターフェイスには、次の表に示すように、一般的に使用される 2 つの実装クラスがあります。

実装クラス 説明する サンプルコード
ClassPathXmlApplicationContext クラスパス ClassPath で指定された XML 構成ファイルをロードし、ApplicationContext のインスタンス化を完了します。 ApplicationContext applicationContext = new ClassPathXmlApplicationContext(String configLocation);
FileSystemXmlApplicationContext 指定されたファイル システム パスに指定された XML 構成ファイルをロードし、ApplicationContext のインスタンス化を完了します。 ApplicationContext applicationContext = new FileSystemXmlApplicationContext(String configLocation);

パラメータ configLocation は、Beans.xml などの Spring 構成ファイルの名前と場所を指定するために使用されます。

ApplicationContext の使用法をデモンストレーションする 

HelloSpring プロジェクトの MainApp クラスの main() メソッドのコードを修正します。具体的なコードは次のとおりです。 

public static void main(String[] args) {
    //使用 FileSystemXmlApplicationContext 加载指定路径下的配置文件 Bean.xml
    BeanFactory context = new FileSystemXmlApplicationContext("D:\\springworkspace\\
HelloSpring\\src\\Beans.xml");
    HelloWorld obj = context.getBean("helloWorld", HelloWorld.class);
    obj.getMessage();
}

 MainApp.java を実行すると、コンソール出力は次のようになります。

メッセージ : Hello World!

おすすめ

転載: blog.csdn.net/qq_43079001/article/details/132099030