【问题标题】:Get a List of Beans for a certain type获取特定类型的 Bean 列表
【发布时间】:2017-08-15 15:15:18
【问题描述】:

我有一种可以提供数据的类和一个注册不同数据提供者的注册表。我正在寻找一种优雅的方式来在 Spring Boot 中实现这一点。 我当前的实现看起来像这样(为简洁起见,代码被缩短):

public interface DataProvider{
    Data getSomeData();
}

public class Registry{
    public register(DataProvider provider){
       //add to internal list
    };

    public List<DataProvider> getProviders(){
       //return providers
    }

    public Data someAggregatedOperation(){ ... }
}

public class Provider1 implements DataProvider { ... }

public class Provider2 implements DataProvider { ... }

现在是接线部分,这是我想改成更优雅的部分:

@Configuration
public class MyAppConfiguration{
    @Bean 
    public Registry providerRegistry(){
        Registry reg = new Registry();
        reg.register(new Provider1());
        reg.register(new Provider2());
        return reg;
    }
}

然后我可以将注册表注入到需要对服务进行操作的其他类中。

我知道 DI 用于为单一类型提供不同的实现,但一次只提供一个。所以 DI 很可能不是正确的工具,我的问题更多是关于 spring,如果有一个我不知道的好方法来实现这一点。 例如,使用限定符对它们进行注释,然后在注册表中使用该限定符解析所有 Bean。

我不想采用的方法是使用自定义注释,然后通过反射解析所有类,实例化它们并将它们放入注册表中。但目前这是我能看到的唯一方法,所以我不必修改配置和手动连接服务。

【问题讨论】:

  • 定义“优雅”对您意味着什么?还有其他一些方法可以做到这一点,但我不知道优雅的解决方案对您意味着什么。您希望所有提供商自动注册还是要控制它?

标签: java spring spring-boot dependency-injection


【解决方案1】:

如果您希望所有这些都被自动装配,您可以自动装配您的接口实现列表。

@Bean
public class Provider1 implements DataProvider { ... }

@Bean
public class Provider2 implements DataProvider { ... }

@Bean
public class Registry{
    @Autowired
    private List<DataProvider> providers;

    public List<DataProvider> getProviders(){
       //return providers
    }

    public Data someAggregatedOperation(){ ... }
}

如果您想继续使用配置类,您可以执行以下操作:

@Bean
public class Provider1 implements DataProvider { ... }

@Bean
public class Provider2 implements DataProvider { ... }

public class Registry{
    private List<DataProvider> providers;

    public Registry(final List<DataProvider> providers) {
      this.providers = providers;
    }

    public List<DataProvider> getProviders(){
       //return providers
    }

    public Data someAggregatedOperation(){ ... }
}

@Configuration
public class MyAppConfiguration{

    @Bean
    @Autowired
    public Registry providerRegistry(final List<DataProvider> providers){
        return new Registry(providers);
    }
}

【讨论】:

  • 这就是我想要的。我真的有一个脑结。我想也许你可以自动装配一个列表,但后来又想“不能,因为这意味着声明多个相同类型的 bean,DI 无法处理”,但如果它们属于相同的类,不合格,但没有接口....谢谢
猜你喜欢
  • 1970-01-01
  • 2017-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-15
  • 2021-03-06
  • 1970-01-01
相关资源
最近更新 更多