繁体   English   中英

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

[英]Get all beans implementing a generic interface in Spring

如何在Spring中获得实现特定通用接口(例如Filter <TestEvent >)的所有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
                }
            }
        }

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

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

    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){ }
    }

它在原型设计方面表现得非常好。

如果你的问题是“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());
}

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

但你的价值不错。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM