簡體   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