2014-09-03 98 views
0

我在通過Weld上下文反射創建對象時遇到問題。帶有Weld-SE上下文的Java反射實例

我從外部文件加載類和它們的配置。

簡化了我的代碼如下所示:

final Class<?> moduleClass = Class.forName(properties.getProperty("className")); 

然後我創建這個類的一個實例

final Constructor<?> constructor = moduleClass.getDeclaredConstructor(); 
module = (Module) constructor.newInstance(); 

模塊類:

@ModuleImpl 
public class ExampleModule extends AbstractModule (implements Module interface) { 

    @Inject 
    private Test test; 

模塊已成功創建,但它沒有焊接上下文來注入Test類。而我找不到正確的方法。我試圖製作自己的製作人,但我對Java SE中的Weld和CDI還不太瞭解。

我破碎的製片人(我認爲它完全以壞)

public class InjectionProvider { 

    @Produces 
    public Module getInsrance(Class<?> clazz) throws ReflectiveOperationException { 
     final Constructor<?> constructor = clazz.getDeclaredConstructor(); 
     return (Module) constructor.newInstance(); 
    } 
} 

我無法找到一些關於這個問題,所以如果有人能幫助我,我會很高興。我真的需要這種創建類的方法,因爲當我需要更改Module類中的某些屬性時,我不想每次都更改我的代碼。

編輯:

我不能與生產商做到這一點。但我找到了一個解決方法。我不確定這是否是一個好的解決方案,但現在可行。

我用Weld上下文創建了一個單例類。

public class TheMightyWeld { 

    private static Weld weld; 

    private static WeldContainer weldContainer; 

    public static WeldContainer getThePowerOfCreation() { 
     if (weldContainer == null) { 
      weld = new Weld(); 
      weldContainer = weld.initialize(); 
     } 
     return weldContainer; 
    } 

    public static void shutdown() { 
     if (weld != null) { 
      weld.shutdown(); 
     } 
    } 

} 

,然後我可以初始化我的應用程序

TheMightyWeld.getPowerOfCreation().instance().select(FXApplicationStarter.class).get().startApplication(primaryStage, getParameters()); 

後來在代碼中,我可以重複使用它的反射

module = (Module) TheMightyWeld.getPowerOfCreation().instance().select(moduleClass).get(); 

EDITED 2:

我發現更好的解決方案。我可以注入焊接實例

@Inject 
private Instance<Object> creator; 

話,我能做的只有這

creator.select(moduleClass).get(); 

我認爲這是一個很好的解決方案。

回答

0

查看編輯後。如果有人有更好的解決方案,我會很高興。

0

我不知道我是否理解你的問題對, 特別是與類加載 相關的部分與生產者中使用的代碼。 我想知道你是否期望注射爲 工作,你通過 Class.forName你自己instanciate的對象。由於通過框架裝飾對象 通常使用修改後的類加載器完成 並返回 修改或裝飾的對象,我想你的 方法禁用此裝飾(依賴注入)。 您不使用呼叫新的離開實例 到類加載器,而是通過反射使用實例化 。

+0

是的。那是我沒有使用Weld classloader的問題。我的製作人只是一個不好的嘗試,不要看它。所以我的問題是:我如何使用Weld來實例化我的對象或類似的方式。因爲我不知道我將實例化哪個類。我只知道他們將實現Module接口,並且我將來可以有很多對象,所以不可能用其他方式實例化它們。 – enkor 2014-09-03 17:14:56

+0

好吧,但這似乎是一個矛盾。由於cdi是聲明性的,它可以與動態類型咬合在一起,就像我說的那樣,正義注入正在發生在你無法通過反射達到的點上。你的對象不知道cdi提供者實例化的方式 – Peter 2014-09-03 17:38:32

+0

也許你可以使用你自己的類加載器調用cdi類加載器,但由於這是一個安全問題,我猜你的焊接提供者(容器)不會允許這種方法,並且因爲使用反射意味着代理反射對象自己,這是非常重要的東西 – Peter 2014-09-03 17:43:40