Spring:実装されたクラスではなく、インターフェイスを自動配線するのはなぜですか?


142

interface IA
{
  public void someFunction();
}

@Resource(name="b")
class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}

@Resource(name="c")
class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

class MyRunner
{

  @Autowire
  @Qualifier("b") 
  IA worker;

  worker.someFunction();
}

誰かが私にこれを説明できますか?

  • Springはどのポリモーフィック型を使用するかをどのようにして知るのですか?
  • 私は必要です@Qualifier@Resource
  • 実装されたクラスではなく、インターフェイスを自動配線するのはなぜですか?

10
インターフェイスを自動配線すると、別の実装で配線できます。これは、クラスではなく、インターフェイスへのコーディングのポイントの1つです。
Dave Newton

別の実装で配線します。質問が理解できません。
Dave Newton

インターフェイスに配線している場合、アクセスする必要があるImplクラス内にデフォルトの可視性メソッドがあるとどうなりますか?パブリックインターフェイスにはデフォルトの修飾子を含めることができないため、そのメソッドスタブをインターフェイスに追加できません。
jlewkovich 16


1
インターフェースを1つだけ実装することは、Javaの世界で受け入れられている愚かな習慣だと思います。その結果、大量のガベージコードが生成されますが、SOLIDおよびOOPのルールに従っていることは誰もが喜んでいます。ギスを使用して、歴史のゴミ箱に春を投げます。
avgolubev

回答:


224

Springはどのポリモーフィック型を使用するかをどのようにして知るのですか?

インターフェイスの実装が1つしかなく、その実装に@ComponentSpringのコンポーネントスキャンが有効になっているアノテーションが付けられている限り、Springフレームワークは(インターフェイス、実装)ペアを見つけることができます。コンポーネントスキャンが有効になっていない場合は、application-config.xml(または同等のSpring構成ファイル)でBeanを明示的に定義する必要があります。

@Qualifierまたは@Resourceが必要ですか?

実装が複数ある場合は、それらをそれぞれ修飾する必要があります。自動配線中に、@Qualifierアノテーションを使用して適切な実装を注入する必要があります@Autowired。@Resource(J2EEセマンティクス)を使用している場合はname、このアノテーションの属性を使用してBean名を指定する必要があります。

実装されたクラスではなく、インターフェイスを自動配線するのはなぜですか?

まず、一般的にインターフェースにコーディングすることは常に良い習慣です。次に、春の場合、実行時に任意の実装を注入できます。典型的な使用例は、テスト段階でモック実装を注入することです。

interface IA
{
  public void someFunction();
}


class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}


class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

class MyRunner
{
     @Autowire
     @Qualifier("b") 
     IA worker;

     ....
     worker.someFunction();
}

Bean構成は次のようになります。

<bean id="b" class="B" />
<bean id="c" class="C" />
<bean id="runner" class="MyRunner" />

または、これらが存在するパッケージでコンポーネントスキャンを有効にした場合は@Component、次のように各クラスを修飾する必要があります。

interface IA
{
  public void someFunction();
}

@Component(value="b")
class B implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someBfunc()
  {
     //doing b things
  }
}


@Component(value="c")
class C implements IA
{
  public void someFunction()
  {
    //busy code block
  }
  public void someCfunc()
  {
     //doing C things
  }
}

@Component    
class MyRunner
{
     @Autowire
     @Qualifier("b") 
     IA worker;

     ....
     worker.someFunction();
}

次にworkerMyRunnerタイプのインスタンスが注入されますB


@stackoverflow質問を編集しても意味がありません。新しいコードが回答に含まれています。それ以外の場合は、それ自体が答えたはずなので、質問は意味がありません。
デイブニュートン

Vikdor-編集を参照してください。それはクラスと注入されたオブジェクトに注釈を付ける正しい方法ですか?
stackoverflow 2012年

1
@VictorDombrovskyは@Autowired @Qualifier("a1") a;有効ですか?
ラッキー

1
@ラッキー間違いを犯した。私は意味@Autowired @Qualifier("a1") A a;
ビクターDombrovsky

1
実装で@Profileを使用して、プログラムの引数またはアプリケーションのプロパティを介して、そのインターフェースにどの実装を注入するかを制御することもできます。
b15

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