2017-10-19 222 views
2

我想獲得Jersey2和吉斯一起合作,這顯然是相當困難的。我已經看到了使用HK2-Guice橋的一些解決方案。但橋依靠獲得在定製Jersey2 ServletContainerinit()的HK2 ServiceLocator例如爲了初始化GuiceBrige如何在Jersey2 ServletContainer中獲得HK2 ServiceLocator?

public class MyServletContainer extends ServletContainer { 
    @Override public void init() { 
    ServiceLocator sloc = getApplicationHandler().getServiceLocator(); 
    ... 
} } 

但不知何故,在新澤西州的latests版本(2.26),在getServiceLocator()不不再存在ApplicationHandler。我如何在這種情況下得到它?

回答

3

聲明:我不使用Guice,所以這不是我測試過的東西。所以我不知道OP是否試圖做甚至會起作用。我只是回答瞭如何獲得ServiceLocator的主要問題。


my comment here提到,從2.26,新澤西州不再對HK2一個依賴。所以整個代碼庫,你將不會再看到一個ServiceLocator參考,而是更高層次InjectionManager。該InjectionManager具有相同的目的的ServiceLocator,但抽象允許依賴注入提供商的不同的實現。這就是爲什麼當使用2.26時,我們需要添加jersey-hk2依賴項。這是InjectionManager的HK2實施。在此實施中,InjectionManager將在適當情況下將呼叫簡單地委託給基礎ServiceLocator

也就是說,ApplicationHandler使您可以立即訪問InjectionManager,而不是ServiceLocator。該ServiceLocator本身是一種服務,所以如果你有一個定位,你可以做以下(這是沒有意義的,但它只是表明我的觀點)

ServiceLocator locator = getServiceLocator(); 
locator = locator.getService(ServiceLocator.class); 

這意味着,你也可以從InjectionManager獲得定位器,這僅僅是一個爲底層定位

InjectionManager im = getApplicationHandler().getInjectionManager(); 
ServiceLocator locator = im.getInstance(ServiceLocator.class); 

有一點需要指出的是,和我的聲明的主要原因高層委託就是你需要調用super.init()第一init()方法,或否則你會得到一個NPE當您嘗試獲取ApplicationHandler時。與此有關的問題是,有很多的初始化完成;幾乎整個應用程序都已初始化。因此,嘗試添加Guice集成可能會也可能不會太晚。

這裏有一些其他的地方我已經看到了這種集成完成。我相信他們會在init()的末尾嘗試做到這一點。

  • ResourceConfig構造函數中,您可以在其中注入InjectionManager
  • Feature在那裏你可以得到InjectionManager通過InjectionManagerProvider靜態方法。
  • 我還沒有見過這樣的作法,但我認爲最佳的位置做橋將是一個ComponentProvider,如the docs提及。我見過的唯一的實現是Spring。您可以在jersey-spring4中看到源代碼。這可能需要更多的工作,但我認爲這將是最合適的位置,因爲它在所有其他選項之前被調用。雖然可能並不需要,因爲我已經看到其他人擺脫了其他兩種選擇。
+0

謝謝,很好的答案。謝謝指出Jersey> 2.26不再對HK2有很大的依賴性,這是從Jersey 1.x遷移到2.x的最大缺點(我們在其他地方使用Guice,所以必須讓兩個DI合作是一個疼痛)。 –