获取所有在Spring中实现通用接口的bean

如何获取Spring中实现特定通用接口(例如Filter <TestEvent >)的所有bean的引用?

这是我想用最少的行数实现的:

 public interface Filter { boolean approve(T event); } public class TestEventFilter implements Filter { public boolean approve(TestEvent event){ return false; } } public class EventHandler{ private ApplicationContext context; public void Eventhandler(DomainEvent event) { // I want to do something like following, but this is not valid code Map filters = context.getBeansOfType(Filter.class); for(Filter filter: filters.values()){ if (!filter.approve(event)) { return; // abort if a filter does not approve the event } } //... } } 

我当前的实现使用reflection来确定filter.approve在调用之前是否接受了该事件。 例如

  Map filters = context.getBeansOfType(Filter.class); for(Filter filter: filters.values()){ if (doesFilterAcceptEventAsArgument(filter, event)) { if (!filter.approve(event)) { return; // abort if a filter does not approve the event } } } 

在什么地方,doFilterAcceptEventAsArgument完成了我想要摆脱的所有丑陋的工作。 有什么建议么?

如果你的问题是“Spring是否有更好的方法来做到这一点”,那么答案就是“不”。 因此,您的方法看起来像无处不在的方法来实现这一点(获取原始类的所有bean,然后使用reflection来查找generics边界并将其与目标的类进行比较)。

通常,如果可能的话,在运行时使用通用信息很棘手。 在这种情况下,您可以获得通用边界,但除了将其用作手动检查的注释forms之外,您实际上并没有从通用定义本身获得太多好处。

在任何情况下,您都必须对返回的对象执行某种检查,因此原始代码块不起作用; 唯一的变化是在doesFilterAcceptEventAsArgument的实现中。 经典的OO方式是使用以下两种方法添加一个抽象超类(并将后者添加到Filter接口):

 protected abstract Class getEventClass(); public boolean acceptsEvent(Object event) // or an appropriate class for event { return getEventClass().isAssignableFrom(event.getClass()); } 

这是一种痛苦,因为你必须在每个实现中实现简单的getEventClass()方法来返回相应的类文字,但这是已知的generics限制。 在语言的范围内,这可能是最干净的方法。

但你的价值不错。

仅供参考,我可以构建的最简单的解决方案是:

  Map filters = context.getBeansOfType(Filter.class); for(Filter filter: filters.values()){ try { if (!filter.approve(event)) { return; // abort if a filter does not approve the event. } } catch (ClassCastException ignored){ } } 

它对原型设计非常有效。