抽象类上的 Spring Autowire 注释:未定义唯一的 bean [英] Spring Autowire Annotation on Abstract class: No unique bean is defined

查看:32
本文介绍了抽象类上的 Spring Autowire 注释:未定义唯一的 bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个抽象类:

@Component
public abstract class BaseReport {

  public void export() {
   ...
}

还有一堆扩展它的类,并覆盖 export() 方法(或不覆盖).

And a bunch of classes that extend it, and override the export() method (or not).

@Component
public final class Report1 extends BaseReport

@Component
public final class Report2 extends BaseReport

我的大多数测试自动装配扩展 BaseReport 的具体类,没有问题:

Most of my tests autowire concrete classes that extend BaseReport, with no problems:

public class Report1Test extends BaseTest {

    @Autowired
    Report1 _report;

public class Report2Test extends BaseTest {

    @Autowired
    Report2 _report;

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

This works fine for autowiring of all classes that extend BaseReport. But I also need to autowire the abstract class itself, BaseReport, to test the export() method.

public class BaseReportTest extends BaseTest {

  @Autowired
  BaseReport _report;

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

When I try to run it I get the infamous:

未定义 BaseReport 类型的唯一 bean:预期单个匹配 bean,但发现 2 [Report1, Report2].

我已经尝试使用@Qualifier,但@Qualifier 的问题在于(据我所知)您使用它来告诉 Spring 您希望使用哪个类——实现接口或扩展抽象类.但这不是我的情况.我想使用抽象类本身.

I've tried using @Qualifier but the problem with @Qualifier is that (as I understand it) you use it to tell Spring which class -- that implements an Interface or extends an Abstract class - you wish to use. But that's not my case. I want to use the abstract class itself.

我也试过使用@Resource,像这样:

I also tried using @Resource, like this:

public class BaseReportTest extends BaseTest {

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

Spring 告诉我没有这个名字的 bean.:(

Spring tells me there is no bean with this name. :(

我该怎么做?

干杯.

推荐答案

抽象类无法实例化,需要使用具体实现.与在常规 java 中一样,如果您尝试实例化抽象类,它会告诉您在其中实现抽象方法.当您这样做时,将创建一个匿名类.它不是抽象类的实例化,而是该抽象类的新子类.

Abstract classes can't be instantiated, you need to use a concrete implementation. Same as in regular java, if you try to instantiate an abstract class, it tells you to implement the abstract methods within. When you do, an anonymous class is created. It's not an instatiation of the abstract class, but a new subclass of that abstract class.

Spring 将寻找扩展您的基类的类,即 Report1 和 Report2,Spring 看到它有多个符合要求的类,但不知道该选择哪一个.因此你会得到有多个匹配 bean 的错误.

Spring will look for classes which extend your base class, being Report1 and Report2, Spring sees it has multiple classes which match the requirements and doesn't know which one to choose. thus you get the error that there are multiple matching beans.

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

You can fix this by making an "adapter" basicly create a concrete class which extends your base-class, implements the abstract methods, but doesn't do anything them. Then you can autowire that implementation and test against it. However your abstract class should allready be tested due to the fact you are testing report 1 and 2. If errors still occur with your base class, it means logic you don't use is causing bugs, which is a bad practice anyway. also with a test coveage tool you could spot unused code that way.

这篇关于抽象类上的 Spring Autowire 注释:未定义唯一的 bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆