2014-11-14 22 views
1

我試圖根據ParameterizedType來選擇一個bean。 Google Guice相關解決方案的答案看起來非常多,但Java EE 7可以解決這個問題嗎?基於類型參數的Java EE注入

public interface Handler<T> { ... } 

@ApplicationScoped StringHandler implements Handler<String> { ... } 
@ApplicationScoped IntegerHandler implements Handler<Integer> { ... } 

然後在其他一些管理的Bean:

@Inject private Instance<Handler<?>> handlers; 

public <T> Handler<T> handlerFor(Class<T> handledClass) 
{ 
    // ??? 
} 

因此,這裏是在實例中的選擇方法,涉及到類型:

<U extends T> Instance<U> select(TypeLiteral<U> subtype, Annotation... qualifiers); 

而對於TypeLiteral的Javadoc只是說,你可以做像

TypeLiteral<List<String>> stringListType = new TypeLiteral<List<String>>() {}; 

這是非常無益的,因爲我不知道編譯時的類型。不過,我確實有Class對象作爲類型參數參數。

看來,Guice可以通過爲你構造TypeLiteral對象來處理這個問題。 Java EE 7中沒有類似的工具嗎?

+0

任何你不能做的原因'@Inject Handler handler'? – 2014-11-15 16:42:51

+0

@John由於類型擦除,如果我使用類型參數並且不知道注入哪一個,容器將不會在運行時知道類型。我很想在運行時將它傳遞給Class,但是沒有選擇(...)。 – Silvaran 2014-11-19 00:43:08

+0

你想要注入的課程是什麼樣的? – 2014-11-20 12:31:49

回答

0

我不太明白你的問題。

但是,也許你可以在運行時獲得通過

String typeName = handledClass.getClass().getTypeParameters()[0].getName(); 

泛型類型然後創建一個通用的註釋爲每個CDI處理程序和基於開關類型:

Annotation qualifier = typeName.equalsIgnoreCase("String") ? new AnnotationLiteral<StrHandler>() {} : new AnnotationLiteral<IntHandler>(){}; 
在您的實例

最後這樣做:

return handlers.select(qualifier).get(); 

編輯:更多關於生成曲alifiers註釋基於AnnotationLiteral上http://docs.jboss.org/weld/reference/latest/en-US/html_single/#_obtaining_a_contextual_instance_by_programmatic_lookup

而且不要忘記使用@Any您注射

@Inject @Any Instance<Handler<?>> instance; 

避免默認注射。

+0

我認爲最接近的是建立一個擴展來自動註釋我的處理程序類,方法是在bean驗證期間查看類型參數並添加類型文字。儘管所有的信息在運行時都可用,但我仍然無法選擇它。如果Instance類具有「select(Type ... typeParameters)」,那麼這將是理想的,然後我可以傳入一個類列表。 – Silvaran 2014-11-19 00:46:31