2011-01-22 66 views
3

我知道一般注射器只能在所有應用中使用一次(啓動時)。但我有以下用例。我爲Executor注入任務實現,然後在該任務中,我有依賴項(可以說FileHandler)每次都必須實例化。我知道的方法是注入提供者(可以說FileHandlerProvider),每次請求都會返回新的實例。問題是FileHandler有它自己的很多依賴項(可以說Parser,OutputPrinter ...)。現在,每次都需要新的實例(因爲實現可能有一些狀態,例如計數器,並且在下一個線程運行時重用相同的實例會成爲問題)。問題是,在注入提供者之後,重用了相同的提供者實例,因此總是使用相同的ParserOuputPrinter創建新的FileHandler。解決方案可能會再次注入ParserProviderOutputPrinterProvider而不是解析器和OuputPrinterFileHandlerProvider,但這只是不正確,它很快變得太複雜,因爲有更多的依賴關係。我現在看到的唯一簡單的解決方案可能是使用Injector in FileHandlerProvider,這將返回新實例FileHandler(和新的依賴項實例)。或者在這種情況下還有另一種更優雅的解決方案?Guice:供應商的注射器

回答

4

您應該只將FileHandler及其依賴關係與默認作用域(即沒有作用域)綁定在一起。然後在每次需要新的FileHandler實例時,注入Provider<FileHandler>並使用其get()。由於FileHandler沒有範圍,因此每次調用get()都需要創建一個新的實例FileHandler ...並且由於其依賴關係也沒有範圍,因此每次都需要創建每個實例的新實例。它應該按照你想要的方式工作。

我認爲你在這裏可能失去的東西是你不需要自己編寫任何這些提供者,只需要注入Provider<FileHandler>,Guice會爲你做這一切。

編輯:下面是我寫的一個小類,它演示了每次創建該類的實例時,新創建的類的依賴關係。

public class Test { 
    public static void main(String[] args) { 
    Injector injector = Guice.createInjector(); 
    injector.getInstance(Test.class); 
    } 

    @Inject public Test(Provider<FileHandler> fileHandlerProvider) { 
    FileHandler fileHandler1 = fileHandlerProvider.get(); 
    FileHandler fileHandler2 = fileHandlerProvider.get(); 

    System.out.println("fileHandler1 == fileHandler2? " + 
     (fileHandler1 == fileHandler2)); 
    System.out.println("fileHandler1.parser == fileHandler2.parser? " + 
     (fileHandler1.parser == fileHandler2.parser)); 
    System.out.println("fileHandler1.print == fileHandler2.printer? " + 
     (fileHandler1.printer == fileHandler2.printer)); 
    } 

    private static class FileHandler { 
    private final Parser parser; 
    private final OutputPrinter printer; 

    @Inject private FileHandler(Parser parser, OutputPrinter printer) { 
     this.parser = parser; 
     this.printer = printer; 
    } 
    } 

    private static class Parser { 
    } 

    private static class OutputPrinter { 
    } 
} 

運行時,該代碼打印:

fileHandler1 == fileHandler2? false 
fileHandler1.parser == fileHandler2.parser? false 
fileHandler1.print == fileHandler2.printer? false

這表明,不僅是每次創建新FileHandler例如,新ParserOutputPrinter實例是創建和注入每次FileHandler以及。

+0

嗨,謝謝你的回答,但問題是,即使我不用手工創建提供者--FileHandler的依賴關係也是相同的重用實例。這可能是因爲Task只創建一次,然後注入提供者(也只有一個實例),提供者創建FileHandler的新實例,但始終使用FileHandler依賴關係的相同實例,因爲它們是在創建時由guice注入提供者的。所以我覺得沒有其他辦法,只是在提供商使用注射器... – nesvarbu 2011-01-24 00:08:29

相關問題