Abstract类上的Spring Autowire Annotation:没有定义唯一的bean

时间:2013-04-12 12:22:02

标签: spring annotations abstract-class autowired

我有一个抽象类:

@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;

这适用于扩展 BaseReport的所有类的自动装配。但是我还需要自动抽象抽象类本身BaseReport来测试export()方法。

public class BaseReportTest extends BaseTest {

  @Autowired
  BaseReport _report;

当我尝试运行它时,我得到了臭名昭着的声明:

没有定义BaseReport类型的唯一bean:期望的单个匹配bean但找到2 [Report1,Report2]。

我已经尝试过使用@Qualifier,但@Qualifier的问题是(据我所知),你用它来告诉Spring哪个类 - 实现一个接口或扩展一个Abstract类 - 你希望使用它。但那不是我的情况。我想使用抽象类本身。

我也尝试过使用@Resource,如下所示:

public class BaseReportTest extends BaseTest {

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

Spring告诉我没有这个名字的豆子。 :(

我该怎么做?

干杯。

1 个答案:

答案 0 :(得分:16)

抽象类无法实例化,您需要使用具体的实现。 与常规java相同,如果您尝试实例化一个抽象类,它会告诉您在其中实现抽象方法。执行此操作时,将创建一个匿名类。它不是抽象类的实例,而是抽象类的新子类。

Spring将查找扩展基类的类,即Report1和Report2, Spring看到它有多个符合要求的类,并且不知道选择哪一个。因此,您会收到有多个匹配bean的错误。

你可以通过制作一个"适配器"来解决这个问题。基本上创建一个扩展基类的具体类,实现抽象方法,但不做任何事情。然后,您可以自动装配该实现并对其进行测试。但是,由于您正在测试报告1和2,因此您的抽象类应该已经过测试。如果您的基类仍然出现错误,则表示您不使用的逻辑导致错误,这无论如何都是不好的做法。还有一个测试工具,你可以用这种方式发现未使用的代码。