「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > Spring Framework における制御の反転

Spring Framework における制御の反転

2024 年 11 月 6 日に公開
ブラウズ:654

Inversion of Control in Spring Framework

制御の反転 (IoC) と依存性注入 (DI) は、Spring Framework の 2 つの基本概念です。従来、オブジェクトは独自の依存関係の作成と管理を担当していました。ただし、IoC は、オブジェクト作成と依存関係管理の制御を Spring のようなフレームワークに引き渡すことで、この責任を逆転させます。

この移行にはいくつかの利点があります:

  • 実装の交換が簡単: コードベースへの最小限の変更で、異なる実装を交換できます。
  • モジュール性の向上: アプリケーション コンポーネントのモジュール化が進み、懸念事項の分離が容易になります。
  • テスト容易性の強化: コンポーネントを個別にテストできるため、モックやその他のテスト戦略が簡素化されます。

IoC は、ファクトリー パターン、ストラテジー パターン、サービス ロケーター パターンなどの設計パターンを含む、さまざまなメカニズムを通じて実装できます。ただし、IoC を実現する最も一般的かつ強力な方法は、依存関係の注入を使用することです。

依存性の注入について理解する

依存性注入 (DI) は、オブジェクト自体が依存関係を作成するのではなく、フレームワークがオブジェクトに依存関係を注入する手法です。 Spring にはさまざまなタイプの DI があります:

  • コンストラクター インジェクション: 依存関係はクラスのコンストラクターを通じて提供されます。
  • セッター注入: 依存関係はセッター メソッドを通じて注入されます。
  • フィールドインジェクション: 注釈を使用して依存関係がフィールドに直接割り当てられます。

たとえば、単純なサービス クラスでは、次のようになります:

@Service
public class OrderService {

    private final PaymentService paymentService;

    @Autowired
    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    public void processOrder(Order order) {
        paymentService.processPayment(order.getPaymentDetails());
    }
}

ここでは、PaymentService はコンストラクター インジェクションを介して OrderService に注入されています。これは、依存関係が明確でテストが容易なため、一般に好まれます。

IoC コンテナ: BeanFactory と ApplicationContext

Spring は、Bean (Spring によって管理されるオブジェクト) のライフサイクルの管理を担当する IoC コンテナーを提供します。このコンテナの基本インターフェイスは BeanFactory です。ただし、ほとんどのアプリケーションは、BeanFactory を拡張して追加機能を提供する ApplicationContext を使用します。

ビーンファクトリー

  • 基本的な IoC コンテナ: Bean を作成および管理するための基本的な機能を提供します。
  • 遅延初期化: Bean は最初にリクエストされたときに作成されます。

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

  • 高度な IoC コンテナ: BeanFactory の基本機能に加えて、次の機能が提供されます。
    • 国際化 (i18n) サポート
    • イベントの伝播と処理
    • 非同期リクエストの処理
    • アスペクト指向プログラミング (AOP) との統合
  • Eager Initialization: アプリケーションの起動時に Bean をインスタンス化して、すぐに使用できるようにします。

例:

// Getting a bean from the ApplicationContext
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyBean myBean = context.getBean(MyBean.class);

この例では、ApplicationContext を使用して Bean を取得します。基本的な BeanFactory を使用している場合、同様の機能が提供されますが、ApplicationContext.

の追加の利点はありません。

ApplicationContext へのアクセス

現在の ApplicationContext にアクセスするには 2 つの一般的な方法があります:

  1. Autowired: ApplicationContext をコンポーネントに直接挿入します。

    @Autowired
    private ApplicationContext applicationContext;
    
  2. ApplicationContextAware: ApplicationContextAware インターフェイスを実装します。これにより、必要に応じて ApplicationContext を取得できるようになります。

    public class MyBean implements ApplicationContextAware {
        private ApplicationContext applicationContext;
    
        @Override
        public void setApplicationContext(ApplicationContext context) throws BeansException {
            this.applicationContext = context;
        }
    }
    

Spring アプリケーションのライフサイクル

Spring アプリケーションが開始されると、一連のステップが実行されます:

  1. 環境変数とプロパティの処理: application.properties または application.yml からの設定を組み込んで、Environment オブジェクトが作成されます。

  2. ApplicationContext の作成: 適切な ApplicationContext タイプが決定され、インスタンス化されます。たとえば、Spring Boot アプリケーションは Java ベースの構成に AnnotationConfigServletWebServerApplicationContext を使用する場合があります。

  3. Bean 定義のロード: Spring は、アノテーション付きクラス、@Configuration クラス、XML ファイルなどの複数のソースから Bean 定義をロードします。各 Bean 定義には、Bean のタイプ、スコープ、依存関係、ライフサイクル コールバックに関する情報が含まれています。

  4. BeanFactoryPostProcessors の処理: これらのプロセッサは、実際の Bean が作成される前に Bean 定義を変更します。

  5. 依存関係の解決と Bean の作成: ApplicationContext は依存関係を解決し、Bean を作成します。 Bean に他の Bean への依存関係がある場合、それらの依存関係が最初に作成されます。

春の豆スコープ

Spring は、コンテナ内の Bean のライフサイクルと可視性を定義するさまざまな Bean スコープをサポートしています。

  • シングルトン (デフォルト): アプリケーション コンテキスト全体に対して Bean の単一インスタンスが作成されます。
  • プロトタイプ: Bean がリクエストされるたびに、新しいインスタンスが作成されます。
  • Request: HTTP リクエスト (Web アプリケーション) ごとに新しい Bean インスタンスが作成されます。
  • セッション: HTTP セッション (Web アプリケーション) ごとに新しい Bean インスタンスが作成されます。

例:

@Bean
@Scope("prototype")
public MyPrototypeBean myPrototypeBean() {
    return new MyPrototypeBean();
}

この例では、コンテナからリクエストされるたびに新しい MyPrototypeBean インスタンスが作成されます。

Bean スコープ内のプロキシ オブジェクト

シングルトン スコープの Bean がプロトタイプ スコープの Bean に依存するシナリオを考えてみましょう。通常、プロトタイプ Bean はシングルトンの初期化中に 1 回だけ作成されます。プロトタイプ Bean の新しいインスタンスが毎回提供されるようにするために、Spring はプロキシ オブジェクトを使用します。

プロキシを使用した例:

@Component
@Scope(value = "singleton")
public class SingletonBean {

    @Autowired
    @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
    private PrototypeBean prototypeBean;

    public void showMessage() {
        System.out.println(prototypeBean.getMessage());
    }
}

ここでは、ScopedProxyMode.TARGET_CLASS により、getMessage() が呼び出されるたびに新しい PrototypeBean インスタンスが返されることが保証されます。

Spring フレームワークと Spring Boot の違い

Spring Boot は、新しい Spring アプリケーションのセットアップと開発を簡素化する Spring Framework の拡張機能です。それは以下を提供します:

  • 組み込みアプリケーション サーバー: 組み込み Tomcat、Jetty、または Undertow を使用して Spring アプリケーションをスタンドアロン アプリとして簡単に実行します。
  • 自動構成: クラスパスおよびその他の設定に基づいて Bean を自動的に構成します。
  • 簡易パッケージ化: アプリケーションを実行可能な JAR または WAR としてパッケージ化します。
  • 統合された監視とヘルスチェック: アプリケーションの健全性とステータスを監視するための組み込みエンドポイント。

Spring Boot の自動構成

自動構成は、クラスパス内の依存関係に基づいて多くのことを構成する Spring Boot の強力な機能です。これは、

のような条件付きアノテーションによって制御されます。
  • @ConditionalOnClass
  • @ConditionalOnMissingClass
  • @ConditionalOnBean
  • @ConditionalOnMissingBean

例:

たとえば、クラスパスに Jackson がある場合、Spring Boot は JSON シリアル化用の ObjectMapper を自動的に構成します。

@Configuration
@ConditionalOnClass(ObjectMapper.class)
public class JacksonAutoConfiguration {
    // Configuration details...
}

ObjectMapper が存在する場合、この構成は自動的に適用されます。それ以外の場合はスキップされます。

アクティブな自動構成の表示

以下を application.properties に追加することで、起動中にアクティブな自動構成をログに記録できます:

logging.level.org.springframework.boot.autoconfigure=DEBUG

これにより、適用された構成と適用されなかった構成を示す詳細なレポートが生成され、アプリケーションの構成のトラブルシューティングや理解に役立ちます。

結論

制御の反転と依存性の注入は、Spring を非常に強力にする柔軟性、モジュール性、テスト容易性を可能にする中心的な概念です。 Spring の IoC コンテナがどのように機能するか、Bean がどのように管理されるか、Spring Boot がこれらの機能をどのように拡張するかを理解することで、堅牢で保守可能なアプリケーションをより効率的に開発できます。

リリースステートメント この記事は次の場所に転載されています: https://dev.to/be11amer/inversion-of-control-in-spring-framework-4mc0?1 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3