サーチ…


備考

大規模なソフトウェアアプリケーションのソースコードは、通常、複数のユニットに編成されています。ユニットの定義は、通常、使用されるプログラミング言語によって異なります。例えば、手続き型プログラミング言語(Cのような)で書かれたコードは、 functionsまたはprocedures編成される。同様に、オブジェクト指向プログラミング言語(Java、Scala、C#など)のコードは、 classesinterfacesなどに編成されていclasses 。これらのコード構成単位は、ソフトウェアアプリケーション全体を構成する個々の単位と考えることができます。

アプリケーションが複数のユニットを持つ場合、それらのユニット間の依存関係は、あるユニットが他のユニットを使用してその機能を完了しなければならない場合に発生します。依存単位は、 consumersと、特定の機能のprovidersとして依存する単位と考えることができます。

最も簡単なプログラミングアプローチは、アプリケーションの全体的な実行のどの時点でどのプロバイダをインスタンス化し、使用し、破壊するかを決定することによって、消費者がソフトウェアアプリケーションのフローを完全に制御することです。消費者は、消費者のdependenciesである実行フロー中にプロバイダを完全に制御できると言われています。プロバイダが独自の依存関係を持っている場合、消費者はプロバイダをどのように初期化(および解放)するべきかを心配する必要があり、ソフトウェアのユニット数が増えるにつれて制御フローがますます複雑になります。このアプローチはまた、ユニット間のカップリングも増加させるため、ソフトウェアの他の部分を破壊することを心配することなくユニットを個別に変更することがますます困難になっています。

Inversion of Control (IoC)は、単位発見、インスタンス化、破壊などの制御フローアクティビティを消費者やプロバイダとは独立したフレームワークにアウトソーシングすることを提唱する設計原理です。 IoCの基本原則は、消費者とプロバイダを切り離し、ソフトウェア部門が依存関係の発見、インスタンス化、クリーンアップを心配する必要がなくなり、ユニットがそれぞれの機能に集中できるようにすることです。このデカップリングは、ソフトウェアの拡張性と保守性を維持するのに役立ちます。

依存性注入は、依存性(プロバイダ)のインスタンスが、消費者がそれらを見つけてインスタンス化する代わりに、ソフトウェアユニット(消費者)に注入される制御原理の逆転を実装する技術の1つである。

Springフレームワークには、Spring管理されたBeanを依存関係として他のSpring管理Beanに注入できるようにする、そのコアに依存性注入モジュールが含まれています。

XML構成を使用して手動で依存性を注入する

次のJavaクラスを考えてみましょう。

class Foo {
  private Bar bar;

  public void foo() {
    bar.baz();
  }
}

見て分かるように、クラスFooは、メソッドfooが正常に動作するために、別のクラスBarインスタンスに対してメソッドbazを呼び出す必要があります。 Barの依存関係であると言われてFooため、 Fooなくても正常に動作することはできませんBarインスタンス。

コンストラクタインジェクション

SpringフレームワークのXML構成を使用してSpring管理Beanを定義する場合、 Foo型のBeanは次のように構成できます。

<bean class="Foo">
  <constructor-arg>
    <bean class="Bar" />
  </constructor-arg>
</bean>

または(より詳細に)

<bean id="bar" class="bar" />

<bean class="Foo">
  <constructor-arg ref="bar" />
</bean>

両方の場合において、スプリングフレームワークは、最初のインスタンス作成BarinjectsのインスタンスにそれをFoo 。この例では、クラスFoo 、パラメータとしてBarインスタンスを取るコンストラクタがあることを前提としています。

class Foo {
  private Bar bar;

  public Foo(Bar bar) { this.bar = bar; }
}

このスタイルは、依存関係( Barインスタンス)がクラスコンストラクタに注入されているため、 コンストラクタインジェクションとして知られています。

特性注入

Bar依存関係をFooに挿入するもう1つの方法は、次のとおりです。

<bean class="Foo">
  <property name="bar">
    <bean class="Bar" />
  </property>
</bean>

または(より詳細に)

<bean id="bar" class="bar" />

<bean class="Foo">
  <property name="bar" ref="bar" />
</bean>

これには、 Fooクラスに次のようなBarインスタンスを受け入れるセッターメソッドが必要です。

class Foo {
  private Bar bar;

  public void setBar(Bar bar) { this.bar = bar; }
}

Java構成を使用して手動で依存性を注入する

上記のXML構成の例は、次のようにJava構成で書き直すことができます。

コンストラクタインジェクション

@Configuration
class AppConfig {
  @Bean
  public Bar bar() { return new Bar(); }

  @Bean
  public Foo foo() { return new Foo(bar()); }
}

特性注入

@Configuration
class AppConfig {
  @Bean
  public Bar bar() { return new Bar(); }

  @Bean
  public Foo foo() {
    Foo foo = new Foo();
    foo.setBar(bar());

    return foo;
  }
}

XML設定による依存関係のオートワイヤリング

依存関係は、Springフレームワークのコンポーネントスキャン機能を使用するときに自動的に呼び出されます。オートワイヤリングを機能させるには、次のXML設定を行う必要があります。

<context:annotation-config/>
<context:component-scan base-package="[base package]"/>

ここで、 base-packageはSpringがコンポーネントスキャンを実行する完全修飾Javaパッケージです。

コンストラクタインジェクション

依存関係は、次のようにクラスコンストラクタを通じて注入できます。

@Component
class Bar { ... }

@Component
class Foo {
  private Bar bar;

  @Autowired
  public Foo(Bar bar) { this.bar = bar; }
}

ここで、 @AutowiredはSpring固有のアノテーションです。 SpringはJSR-299もサポートし、他のJavaベースの依存性注入フレームワークへのアプリケーション移植性を可能にします。これにより、 @Autowired@Injectに置き換えることができます:

@Component
class Foo {
  private Bar bar;

  @Inject
  public Foo(Bar bar) { this.bar = bar; }
}

特性注入

依存関係は、次のようにsetterメソッドを使用して注入することもできます。

@Component
class Foo {
  private Bar bar;

  @Autowired
  public void setBar(Bar bar) { this.bar = bar; }
}

フィールドインジェクション

Autowiringでは、クラスインスタンス内のフィールドを次のように直接初期化することもできます。

@Component
class Foo {
  @Autowired
  private Bar bar;
}

Springバージョン4.1+では、オプションの依存関係のためにOptionalを使用できます。

@Component
class Foo {

    @Autowired
    private Optional<Bar> bar;
}

コンストラクタDIにも同じアプローチを使用できます。

@Component
class Foo {
    private Optional<Bar> bar;

    @Autowired
    Foo(Optional<Bar> bar) {
        this.bar = bar;
    }
}

Java設定による依存関係の自動配線

Java構成によるコンストラクター注入は、次のような自動配線を利用することもできます。

@Configuration
class AppConfig {
  @Bean
  public Bar bar() { return new Bar(); }

  @Bean
  public Foo foo(Bar bar) { return new Foo(bar); }
}


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow