2015-10-21 61 views
1

我們的項目設置如下:創建與注入器無關的Guice單例程

1)主模塊:包含啓動Spark流服務器的驅動程序。它有自己的Guice注射器。

2)當消息進入時,它會轉到另一個模塊,創建它自己的Guice注入器。

3)該模塊使用其他模塊中的類,這些模塊本身使用從屬模塊。這些模塊中的每一個都創建了自己的Guice注入器,以便它可以獨立工作,單獨測試等。

以下是一個問題:現在我們需要一個Singleton,但創建爲@Singleton的對象綁定到注入器(而不是ClassLoader),所以當噴射器消失時,物體消失。

問題:

1)我們的建築是壞的嗎?我們是不是應該在每個模塊中創建一個注入器?

2)我們如何創建一個即使噴油器消失也會保留在ClassLoader中的Singleton?

順便說一句,我們在Guice上使用Netflix Governator。

注意:回答這個問題被認爲是重複的這個問題沒有回答如何將頂層模塊上創建的「單個」注入器傳遞給子模塊。另外,如果子模塊本身沒有注入器,我們可以爲它們編寫獨立的單元測試嗎?

+0

'Singletons'在Java反模式,因爲它們並不像你想象的那樣綁定到JVM上,而是綁定到一個'ClassLoader'上,'JVM'實例可以有很多實例並且是一個根本不同的範圍。 如果您閱讀Guice文檔,有一個Module * inheritance *類型的概念,它允許具有父模塊範圍的子模塊*。這是你需要使用的。 –

+0

這個問題有點令我困惑,因爲我不知道你的意思是「架構模塊」還是「Guice'模塊」 –

+0

Tavin - 「module」是指Maven下的一個模塊。每個都有自己的pom.xml,每個都有自己的Guice模塊。 – DilTeam

回答

2

問題2的想法是使用一個提供程序,您可以在所有不同的模塊中進行綁定。該提供者將訪問Guice外部存在的單例。

我製作了一個簡單的例子,我可以訪問一個靜態字段。你可以改變它來使用適合你需要的Singleton模式的實現。

public class SingletonProvider implements Provider<TheSingleton> { 

    private static final TheSingleton instance = new TheSingleton(); 
    @Override 
    public TheSingleton get() { 
     return instance; 
    } 
} 

然後我們結合這給我們不同的模塊

public class Module1 extends AbstractModule { 

    @Override 
    protected void configure() { 
     bind(TheSingleton.class).toProvider(SingletonProvider.class); 
    } 
} 
public class Module2 extends AbstractModule { 

    @Override 
    protected void configure() { 
     bind(TheSingleton.class).toProvider(SingletonProvider.class); 
    } 
} 

然後我創建了返回同一實例兩個不同的噴油器

public class Test { 
    public static void main(String[] args) { 
     Injector injector1 = Guice.createInjector(new Module1()); 

     TheSingleton instance = injector1.getInstance(TheSingleton.class); 
     System.out.println("instance = " + instance); 

     Injector injector2 = Guice.createInjector(new Module2()); 
     TheSingleton instance2 = injector2.getInstance(TheSingleton.class); 
     System.out.println("instance2 = " + instance2); 


    } 
} 
+0

你保留SingletonProvider中的哪個模塊? – DilTeam

+0

@DilTeam提供者不在任何模塊中。每個注入器將創建它自己的提供者實例,並使用它來獲取TheSingleton.class的實例。您可以將其視爲可以在模塊之外提供訪問的類。 –

+0

您是否在調試器中確認它們確實是相同的對象而不是副本? – DilTeam