Java SpringCore:为@Bean方法使用接口结果类型

Java SpringCore:为@Bean方法使用接口结果类型,java,spring,dependency-injection,Java,Spring,Dependency Injection,我正在阅读Spring core文档,并试图理解这一部分: 您还可以使用接口(或基类)返回类型声明@Bean方法,如下所示 示例显示: 但是,这将高级类型预测的可见性限制在 指定的接口类型(TransferService)。然后,使用完整类型 (TransferServiceImpl)容器只知道一次,受影响的 单例bean已经实例化。非懒惰单例bean获得 根据它们的声明顺序实例化,所以您可以看到 不同的类型匹配结果取决于另一个组件 尝试通过未声明的类型(如@Autowired)进行匹配 Tra

我正在阅读Spring core文档,并试图理解这一部分:

您还可以使用接口(或基类)返回类型声明@Bean方法,如下所示 示例显示:

但是,这将高级类型预测的可见性限制在 指定的接口类型(TransferService)。然后,使用完整类型 (TransferServiceImpl)容器只知道一次,受影响的 单例bean已经实例化。非懒惰单例bean获得 根据它们的声明顺序实例化,所以您可以看到 不同的类型匹配结果取决于另一个组件 尝试通过未声明的类型(如@Autowired)进行匹配 TransferServiceImpl,它只解析transferService bean一次 已实例化)

好吧,这听起来很合理,我想试试看区别,所以我想出了以下代码:

public interface Hotel { }

public class LuxuryHotel implements Hotel {

  private String name;

  public LuxuryHotel(String name) {this.name = name;}

  public String getName() {return name;}
}

public class HotelGuest {

  @Autowired
  private LuxuryHotel hotel;

  public void info() {
    System.out.println("I live in the luxury hotel " + hotel.getName());
  }
}

@Configuration
public class JavaConfig {

  @Bean
  public HotelGuest guest(Hotel hotel) {
    return new HotelGuest();
  }

  @Bean
  public Hotel blueHotel() {
    return new LuxuryHotel("Blue Hotel");
  }

  @Bean
  public LuxuryHotel redHotel() {
    return new LuxuryHotel("Red Hotel");
  }
}

public class Main {

  public static void main(String[] args) {
    AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(JavaConfig.class);
  }
}
现在,根据上面文档中的引用,我会预期以下行为:Spring尝试按照config类中声明的顺序实例化bean。因此,它将首先尝试实例化
HotelGuest
bean。现在,它需要将依赖项注入类型为
LuxuryHotel
@Autowired
字段中,并寻找合适的bean。由于其他两个bean尚未初始化,Spring还不知道bean
blueHotel()
实际上是一个
LuxuryHotel
,因为它的返回类型只是
Hotel
。因此,根据我的预期,它应该只看到一个匹配的bean被自动连接,即
redHotel()
,它明确地声明
LuxuryHotel
为其返回类型


但实际的行为是:Spring抛出一个错误,告诉您有两个符合条件的bean可以注入这个字段。因此,我想了解,解释这部分文档的正确方法是什么,以及如何修改示例以实际查看使用接口返回类型和具体返回类型之间的不同行为?

POJO不应该是bean。还可以阅读关于限定符的内容,我选择了@Jens。您可能希望使用@Order实现基于顺序的spring初始化的另一个方面是spring初始化在几个过程中进行。首先,它解决了确定依赖关系图(并且它可以满足依赖关系)的问题,然后实例化bean。在实例化时,它意识到它有多个候选者。谢谢!是的,我知道我可以使用Order和Qualifier来定制Bean选择。但是,正如我所写的,实际的问题是:如何在使用接口返回类型和Bean方法的具体返回类型之间重现不同的行为,qouted docu正在讨论这一点?我认为我实现的案例将是docu正在解释的一个例子(实际的bean类型事先不知道),但显然这个案例不起作用,那么,重新说明使用接口返回类型和具体返回类型之间的区别的一个例子是什么呢?
public interface Hotel { }

public class LuxuryHotel implements Hotel {

  private String name;

  public LuxuryHotel(String name) {this.name = name;}

  public String getName() {return name;}
}

public class HotelGuest {

  @Autowired
  private LuxuryHotel hotel;

  public void info() {
    System.out.println("I live in the luxury hotel " + hotel.getName());
  }
}

@Configuration
public class JavaConfig {

  @Bean
  public HotelGuest guest(Hotel hotel) {
    return new HotelGuest();
  }

  @Bean
  public Hotel blueHotel() {
    return new LuxuryHotel("Blue Hotel");
  }

  @Bean
  public LuxuryHotel redHotel() {
    return new LuxuryHotel("Red Hotel");
  }
}

public class Main {

  public static void main(String[] args) {
    AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(JavaConfig.class);
  }
}