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

Ola*_*ahl 5 java spring

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

}
Run Code Online (Sandbox Code Playgroud)

我当前的实现使用反射来确定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
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

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

Ola*_*ahl 5

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

    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){ }
    }
Run Code Online (Sandbox Code Playgroud)

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


And*_*yle 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());
}
Run Code Online (Sandbox Code Playgroud)

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

但你的就其价值来说还是不错的。