web-dev-qa-db-ja.com

抽象クラスでのSpringAutowireアノテーション:一意のBeanが定義されていません

抽象クラスがあります:

@Component
public abstract class BaseReport {

  public void export() {
   ...
}

そして、それを拡張し、export()メソッドをオーバーライドする(またはオーバーライドしない)クラスの束。

@Component
public final class Report1 extends BaseReport

@Component
public final class Report2 extends BaseReport

私のテストのほとんどは、BaseReportを拡張する具象クラスを問題なく自動配線します。

public class Report1Test extends BaseTest {

    @Autowired
    Report1 _report;

public class Report2Test extends BaseTest {

    @Autowired
    Report2 _report;

これは、extend BaseReportであるすべてのクラスの自動配線で正常に機能します。ただし、export()メソッドをテストするには、抽象クラス自体であるBaseReportも自動配線する必要があります。

public class BaseReportTest extends BaseTest {

  @Autowired
  BaseReport _report;

私がそれを実行しようとすると、私は悪名高いものになります:

BaseReportタイプの一意のBeanは定義されていません:単一の一致するBeanが必要ですが、2 [Report1、Report2]が見つかりました。

@Qualifierを使用してみましたが、@ Qualifierの問題は、(私が理解しているように)使用するクラス(インターフェイスを実装するクラスまたは抽象クラスを拡張するクラス)をSpringに指示するために使用することです。しかし、それは私の場合ではありません。抽象クラス自体を使いたい。

また、次のように@Resourceを使用してみました。

public class BaseReportTest extends BaseTest {

  @Resource(name = "baseReport")
  BaseReport _report;

春は、この名前の豆はないと言っています。 :(

これどうやってするの?

乾杯。

9
Robert Bowen

抽象クラスはインスタンス化できません。具体的な実装を使用する必要があります。通常のJavaと同じように、抽象クラスをインスタンス化しようとすると、その中に抽象メソッドを実装するように指示されます。これを行うと、匿名クラスが作成されます。これは抽象クラスの説明ではなく、その抽象クラスの新しいサブクラスです。

Springは、基本クラスを拡張するクラス(Report1とReport2)を探します。Springは、要件に一致する複数のクラスがあることを確認し、どれを選択するかわかりません。したがって、一致するBeanが複数あるというエラーが発生します。

これを修正するには、基本的に「アダプタ」で基本クラスを拡張し、抽象メソッドを実装する具象クラスを作成しますが、何もしません。次に、その実装を自動配線して、それに対してテストできます。ただし、レポート1と2をテストしているため、抽象クラスはすでにテストされているはずです。それでも基本クラスでエラーが発生する場合は、使用しないロジックがバグを引き起こしていることを意味します。これはとにかく悪い習慣です。また、テストカバーツールを使用すると、未使用のコードをそのように見つけることができます。

16
G-Man