我知道一般注射器只能在所有應用中使用一次(啓動時)。但我有以下用例。我爲Executor注入任務實現,然後在該任務中,我有依賴項(可以說FileHandler
)每次都必須實例化。我知道的方法是注入提供者(可以說FileHandlerProvider
),每次請求都會返回新的實例。問題是FileHandler
有它自己的很多依賴項(可以說Parser
,OutputPrinter
...)。現在,每次都需要新的實例(因爲實現可能有一些狀態,例如計數器,並且在下一個線程運行時重用相同的實例會成爲問題)。問題是,在注入提供者之後,重用了相同的提供者實例,因此總是使用相同的Parser
和OuputPrinter
創建新的FileHandler
。解決方案可能會再次注入ParserProvider
和OutputPrinterProvider
而不是解析器和OuputPrinter
在FileHandlerProvider
,但這只是不正確,它很快變得太複雜,因爲有更多的依賴關係。我現在看到的唯一簡單的解決方案可能是使用Injector in FileHandlerProvider
,這將返回新實例FileHandler
(和新的依賴項實例)。或者在這種情況下還有另一種更優雅的解決方案?Guice:供應商的注射器
3
A
回答
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
例如,新Parser
和OutputPrinter
實例是創建和注入每次FileHandler
以及。
相關問題
- 1. Guice和注射器
- 2. Guice的全球注射器
- 3. 黃瓜與Guice - 多個guice注射器
- 4. Guice:使用注射器?
- 5. 角度注射(未知供應商)
- 6. 吉斯:輔助注射和供應商
- 7. AngularJS $注射器:未知提供商
- 8. Guice與供應商或FactoryModuleBuilder協作注入
- 9. Guice按需注射
- 10. 如何添加另一個供應商到注射器?
- 11. 如何中介模塊供應商融入注射器樹
- 12. 定義自定義提供商和$注射器:unpr不明提供商
- 13. 如何在guice提供程序中使用guice注入器?
- 14. Guice局部注射示例
- 15. Guice注射不與Dropwizard
- 16. scala-guice和輔助注射
- 17. AngularJS - 供應商和注射的Karma測試
- 18. 注射服務爲一體的供應商
- 19. 未捕獲的錯誤:[$注射器:unpr]未知提供商:
- 20. 錯誤:[$注射器:unpr]未知提供商:UserServiceProvider < - UserService < - fbLoginCtrl
- 21. angular.js:錯誤:[$注射器:unpr]未知提供商
- 22. 錯誤:[$注射器:unpr]未知提供商:RestaurantListServiceProvider < - RestaurantListService < - ReservationController
- 23. 錯誤:[$注射器:unpr]未知提供商:productResourceProvider < - productResource < - ProductListCtrl
- 24. 錯誤:[$注射器:unpr]未知提供商:
- 25. 錯誤:[$注射器:unpr]未知提供商:$ cordovaFileProvider < - $ cordovaFile < - DashCtrl
- 26. AngularJS - 錯誤:[$注射器:unpr]未知提供商:
- 27. 錯誤:$注射器:unpr未知提供商角
- 28. 角錯誤:$注射器:unpr未知提供商
- 29. 茉莉花測試:錯誤:[$注射器:unpr]未知提供商:
- 30. 了問題$注射器:unpr未知提供商爲$餅乾ngCookies
嗨,謝謝你的回答,但問題是,即使我不用手工創建提供者--FileHandler的依賴關係也是相同的重用實例。這可能是因爲Task只創建一次,然後注入提供者(也只有一個實例),提供者創建FileHandler的新實例,但始終使用FileHandler依賴關係的相同實例,因爲它們是在創建時由guice注入提供者的。所以我覺得沒有其他辦法,只是在提供商使用注射器... – nesvarbu 2011-01-24 00:08:29