簡體   English   中英

我如何/應該創建自己的Guice范圍

[英]How / Should I create my own Guice Scope

我們有一個舊版應用程序,現在可以在單個JVM中加載多個實例。 現在,我們在更新的代碼中使用Guice進行依賴項注入,但是現在該解決舊的應用程序代碼了。

遺留應用程序在許多線程中工作,這些線程是相當隨機創建的(盡管所有線程都是通過助手創建的,因此我們可以在其中添加代碼),我認為我們需要一個范圍來覆蓋該應用程序的每個實例。

那么,我應該創建自己的范圍嗎? 我應該如何覆蓋多個線程? 我可以使用應用程序的每個實例所具有的唯一字符串來在每個線程的開頭查找正確的作用域嗎?

對范圍的需求可以歸結為一個問題: 您是否希望能夠根據您定義的環境注入完全相同的對象實例,但是讓它們在您定義的環境之間有所不同? (這意味着,對於對象Foo,每個舊應用程序實例將收到一個不同的Foo,但是在該舊應用程序實例的環境中,如果請求,則始終會收到相同的Foo實例。)如果是,則范圍是你想要什么。

關於示波器的設計和實現,有兩個重要的注意事項:

  1. 所有范圍都實現為可能緩存的提供程序包裝器。
  2. 除了同步Singleton創建之外,Guice沒有線程的內部概念。

單例作用域只是提供者包裝器,它一次創建對象並將其保存以永久返回。 請求和會話作用域僅確定當前的請求或會話,將提供程序包裝起來以返回相同的實例,或者在必要時委托內部提供程序創建一個新的實例。 對於無作用域的對象或假設的DoNothingScope,不需要包裝—您每次都可以得到一個新對象,就像普通的Provider一樣。 最后,重要的是,對於Guice的“ 自定義范圍”頁面上的基於線程的范圍示例,范圍僅返回一個匿名內部提供程序,該提供程序檢查ThreadLocal<Map<Key, Object>>以在需要時返回現有對象。


您可以使用“ 自定義范圍”示例作為起點,進行以下更改:

  • 保留Map<LegacyAppInstance, Map<Key, Object>> ,因為您要Map<LegacyAppInstance, Map<Key, Object>>應用程序實例而不是線程。 您唯一的String可以很好地用作鍵,但是我對它的可訪問性的細節還不夠了解。
  • 您還將需要保留ThreadLocal<LegacyAppInstance> (或ThreadLocal<String> ),這將使您可以隨時確定從Thread到舊應用程序實例的映射。
  • enter()exit()將需要進行一些更改:您需要創建一個enter(LegacyAppInstance) ,您可以從新線程中調用該方法以建立從線程到LegacyAppInstance的鏈接。 您只需調用exit即可破壞該LegacyAppInstanceMap<Key, Object> ,因此所有這些創建的對象都可以被垃圾收集。
  • 除此之外,它是相同的:返回一個Provider(可能是匿名內部Provider),該Provider確定您所在的線程,確定正在運行的LegacyAppInstance,然后返回一個現有實例或根據需要創建一個新實例。 。

別忘了將Scope實例本身綁定為單例( toInstance綁定一定是Singletons),因此您可以從線程創建助手中獲取它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM