Spring: 获取特定接口AND类型的所有Bean

Spring: get all Beans of certain interface AND type

在我的 Spring 引导应用程序中,假设我在 Java 中有接口:

public interface MyFilter<E extends SomeDataInterface> 

(一个很好的例子是 Spring 的 public interface ApplicationListener< E extends ApplicationEvent >

我有几个实现,例如:

@Component
public class DesignatedFilter1 implements MyFilter<SpecificDataInterface>{...}

@Component
public class DesignatedFilter2 implements MyFilter<SpecificDataInterface>{...}

@Component
public class DesignatedFilter3 implements MyFilter<AnotherSpecificDataInterface>{...}

然后,在某些对象中,我有兴趣利用所有实现 MyFilter< SpecificDataInterface > 但不是 MyFilter< AnotherSpecificDataInterface > [的过滤器

这个的语法是什么?

以下将把每个具有扩展 SpecificDataInterface 类型的 MyFilter 实例作为通用参数注入到列表中。

@Autowired
private List<MyFilter<? extends SpecificDataInterface>> list;

您可以简单地使用

@Autowired
private List<MyFilter<SpecificDataInterface>> filters;

编辑 2020 年 7 月 28 日:

因为不再推荐现场注入Constructor injection should be used instead of field injection

使用构造函数注入:

class MyComponent {

  private final List<MyFilter<SpecificDataInterface>> filters;

  public MyComponent(List<MyFilter<SpecificDataInterface>> filters) {
    this.filters = filters;
  }
  ...
}

如果您需要地图,可以使用以下代码。关键是你定义的方法

private Map<String, MyFilter> factory = new HashMap<>();

@Autowired
public ReportFactory(ListableBeanFactory beanFactory) {
  Collection<MyFilter> interfaces = beanFactory.getBeansOfType(MyFilter.class).values();
  interfaces.forEach(filter -> factory.put(filter.getId(), filter));
}

如果您想要 Map<String, MyFilter>,其中 key (String) 代表 bean 名称:

private final Map<String, MyFilter> services;

public Foo(Map<String, MyFilter> services) {
  this.services = services;
}

recommended 替代:

@Autowired
private Map<String, MyFilter> services;