java - 如何在 Spring 中实现基于注解的集合合并?
问题描述
我正在尝试使用一组特定类型的所有 bean 初始化一个 Spring 组件(实际上,任何我可以迭代的东西)。
Spring 核心文档讨论了集合合并,但仅在基于注释的配置的上下文中。
假设我有以下配置
@Configuration
public class MyConfig {
@Bean
public SomeInterface single() {
return new SomeInterface() {};
}
@Bean
public Set<SomeInterface> multi() {
return Collections.singleton(
new SomeInterface() {}
);
}
}
接口定义为
public interface SomeInterface {}
我希望这个组件能够获得两个 bean 的聚合——一些包含两个匿名类的集合。
@Component
public class MyComponent {
public MyComponent(Set<SomeInterface> allInterfaces) {
System.out.println(allInterfaces.size()); // expecting 2, prints 1
}
}
我明白为什么 Spring 会达到它的结果;它看到这个方法需要一个Set<SomeInterface>
并且MyConfig::multi
是一个类型的bean Set<SomeInterface>
,所以它会自动装配它。
如果我将签名更改为Collection<SomeInterface>
,它会自动与MyConfig::single
. 再次,我明白了原因:没有什么完全匹配的,但是有类型的 bean SomeInterface
(在这种情况下,只有一个),所以它构造了它们的临时集合并自动装配。很好,但不是我想要的。
我希望解决方案是可扩展的,这样如果添加了另一个 bean,则依赖组件不需要更改。我尝试过使用两个参数,每个参数都有一个@Qualifier
, 并且有效但不可扩展。
我怎样才能让它工作?
解决方案
正如您已经提到的,MyConfig::multi
是 type 的 bean Set<SomeInterface>
,因此自动装配Collection<Set<SomeInterface>>
将为您提供所有这些集合。以下应该工作
public MyComponent(Collection<SomeInterface> beans,
Collection<Set<SomeInterface>> beanSets) {
// merge both params here
}
如果您需要在多个位置进行所有实现,则定义另一个包含合并集合的 bean 并自动装配该 bean 可能是有意义的:
static class SomeInterfaceCollection {
final Set<SomeInterface> implementations;
SomeInterfaceCollection(Set<SomeInterface> implementations) {
this.implementations = implementations;
}
}
@Bean
public SomeInterfaceCollection collect(Collection<SomeInterface> beans,
Collection<Collection<SomeInterface>> beanCollections) {
final HashSet<SomeInterface> merged = ...
return new SomeInterfaceCollection(merged);
}
推荐阅读
- reactjs - 运行 nodemon server.js 时显示错误
- java - windowbackground 在深色和浅色主题中不起作用
- python - 在 TensorFlow Dataset 中使用 window() 函数访问多行
- swift - 在 Swift 中传递并打印枚举中的所有案例
- java - SpringData Pageable Projection with LeftJoin with JPA2.1
- sql - 我可以使用 Spark SQL 直接查询 TSV 文件吗?
- r - 重新排序观星器中的变量
- javascript - Vue - 使用 axios 请求填充道具的问题
- javascript - 使用 .htaccess 导航到 URL 中最后一个目录的父目录
- c++ - 为什么文件的 std::remove 总是返回-1?