[英]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.