基于外部配置创建多个相同类型的bean

Creating multiple beans of same type based on external config

class SomeClass() implements Runnable
{
    private SomeDevice someDevice;
    private SomeOtherDevice someOtherDevice;
    
    @Override
    public void run()
    {
        ...
        someDevice.doSomething();
        ...
        someOtherDevice.doSomething();
    }
}
@Configuration
class Config
{
    @Bean
    @Scope("prototype")
    public SomeDevice someDevice { return new SomeDevice() }
    @Bean
    @Scope("prototype")
    public SomeOtherDevice someOtherDevice { return new SomeOtherDevice() }
}

我对 Spring 非常非常陌生,需要实现一些复杂的东西。

我有一个外部配置文件,指定我将拥有多少个 SomeDevice,以及每个 SomeDevice 将侦听的端口。 SomeClass 的实例将负责每个 SomeDevice。所以我将在 SomeClass1 中使用 SomeDevice1 运行,在 SomeClass2 中使用 SomeDevice2 运行,等等。 每个 SomeClass 还需要它自己的 SomeOtherDevice 实例。

我希望能够手动创建这些 bean,这样我就可以:

  1. 读取我的外部配置文件并创建适当数量的 SomeDevice
  2. 通过调用 someDevice.setPort()
  3. 根据外部配置指定它们的每个端口
  4. 将它们放入它们自己的 SomeClass 实例中。
  5. SomeClass 还需要它自己的 SomeOtherDevice 实例(SomeOtherDevice 不需要外部配置信息)

我已经尝试使用 bean 工厂来执行此操作,但在使用 bean 工厂创建 SomeDevice bean 后,我无法让 SomeClass 找到它们。它无法通过名称找到它们,只能通过 class。但是因为我将有多个 SomeDevice.class bean,所以我希望能够通过名称找到它们(并在创建它们时为它们指定唯一的名称)。我什至不确定我是否以“最佳”方式处理事情。如果有人能指出我正确的方向,我将不胜感激。

编辑:我忘了说我不想更改 SomeDevice 的源代码。所以我不能给那个 class 添加 Spring 注释,除非它是非常必要的。

您通常不希望通过解析外部配置来创建 bean。那将是重新发明 Spring 框架,既然你说你是 Spring 的新手,那你就错了。 你想要的是有条件地激活你想要的bean。因此,您将有多个 SomeClassSomeDevice,但根据运行时(外部)配置只会创建一个或多个 bean。 请参阅文档的 this 部分。

如果你不知道怎么写你自己的条件,google它。您也可以从“Spring 引导配置文件”开始,这是所有条件中最简单的,并且是 OOTB。

编辑: 如果您必须在运行时读取外部文件并注册 bean,请参阅 this 教程。但是,通常有更简单的方法,如上所述。