2010-07-12 32 views
5

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

这就是我想要的实现与线的最低数量:

public interface Filter<T extends Event> { 

    boolean approve(T event); 

} 


public class TestEventFilter implements Filter<TestEvent> { 

    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<String, Filter> filters = context.getBeansOfType(Filter<event.getClass()>.class); 
     for(Filter filter: filters.values()){ 
      if (!filter.approve(event)) { 
       return; // abort if a filter does not approve the event 
      } 
     } 
     //... 
    } 

} 

我的当前实现使用反射来确定是否filter.approve并调用它之前接受的事件。 例如

 Map<String, Filter> 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 
       } 
      } 
     } 

凡doesFilterAcceptEventAsArgument做所有的丑恶的工作,我想希望得到远离。有什么建议么?

回答

2

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

一般来说,如果可能的话,在运行时使用通用信息是非常棘手的。在这种情况下,您可以获得泛型边界,但您从泛型定义本身中获益不大,除了将其用作手动检查的批注形式之外。

在任何情况下,您将不得不对执行一些类型的返回对象的检查,因此您的原始代码块不会工作;唯一的变化是执行doesFilterAcceptEventAsArgument。经典的OO方式,将如下两种方法来添加一个抽象超(并添加后者Filter接口):

protected abstract Class<E> getEventClass(); 

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

这是一种痛苦的,因为你必须要实现琐碎每个实现中的方法都返回适当的类文字,但这是泛型的已知限制。在语言的范围内,这可能是最干净的方法。

但是你的很好,它的价值。

+0

谢谢,就像我怀疑的一样。 – 2010-07-12 12:53:28

4

仅供参考,我可以构建最简单的办法是这样的:

Map<String, Filter> 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){ } 
    } 

而且它相当奏效的原型。