[英]How can I cleanly override the default ServiceLocator used by Jersey?
我正在開發一個應用程序,它使用Jersey(2.5)作為其REST前端,Jetty作為嵌入式HTTP(S)服務器,兩者都采用所謂的“嵌入式”方式,例如。 不依靠制作.war
並部署它,而是通過程序化配置處理程序,資源,注入......
我想以某種方式覆蓋Jersey在服務器端使用的HK2 ServiceLocator
,或者可能為父服務定位器提供一個父服務器來解析在應用程序的REST部分之外定義的依賴關系。 從我看到的代碼來看,這似乎是不可能的:ServiceLocator通過調用Injections
在ApplicationHandler
實例化:
if (customBinder == null) {
this.locator = Injections.createLocator(new ServerBinder(application.getProperties()), new ApplicationBinder());
} else {
this.locator = Injections.createLocator(new ServerBinder(application.getProperties()), new ApplicationBinder(),
customBinder);
}
注射中的代碼告訴我以下內容:
public static ServiceLocator createLocator(Binder... binders) {
return _createLocator(null, null, binders);
}
這意味着新創建的服務定位器具有一些任意生成的名稱,並且沒有父級。
有沒有(干凈的)方法來改變這種行為,以便我自己注入ServiceLocator作為應用程序的父類?
我知道這個答案有點晚了。 我在同一個問題上掙扎,但在Dropwizard框架中。 經過一些調試,我看到了一些令我開心的代碼!
final ServiceLocator locator = (ServiceLocator) webConfig.getServletContext()
.getAttribute(ServletProperties.SERVICE_LOCATOR);
這段代碼在jerseyes WebComponent構造器中。 所以解決方案是為ServletContext提供ServletProperties.SERVICE_LOCATOR
。 在Dropwizard環境中,我實現了它
environment.getApplicationContext().getAttributes().setAttribute(ServletProperties.SERVICE_LOCATOR, locator);
我們有類似的設置,我已經設法使用jwells131313的新bridgeServiceLocator API來使用我們的架構。
編輯:請注意,當前的HK2橋接實現意味着Singleton實例僅對其創建的ServiceLocator是本地的,這意味着橋接體系結構可以包含多個Singleton服務的實例。 請參閱此問題以獲取更多信息和可能的解決方法/替代方法。
編輯#2:修復了ServiceLocator橋中的上述錯誤。 修復程序將在hk2 2.5.0-b07或更高版本中
基本上我創建了一個Feature
實現來設置橋接並將其注冊到Jersey(在我們的實例中通過ServletContainer
)。
public class InjectionBridge implements Feature
{
private static ServiceLocator _applicationServiceLocator;
private final ServiceLocator _serviceLocator;
@Inject
private InjectionBridge(ServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
}
@Override
public boolean configure(FeatureContext context)
{
if (_applicationServiceLocator != null)
ExtrasUtilities.bridgeServiceLocator(_serviceLocator, _applicationServiceLocator);
return true;
}
public static void setApplicationServiceLocator(ServiceLocator applicationServiceLocator)
{
_applicationServiceLocator = applicationServiceLocator;
}
}
然后,從應用程序代碼調用setApplicationServiceLocator
並使用應用程序創建的ServiceLocator
來管理應用程序資源。
這意味着Jersey RESTful服務實現現在可以簡單地使用@Inject
批注聲明字段,並訪問那些注入資源以服務請求。
在創建ServiceLocator之后,您無法使一個ServiceLocator成為另一個ServiceLocator的父級。
但是,從hk2 2.4.0-b11開始,將能夠擁有ServiceLocator - > ServiceLocator橋。 因此,ServiceLocator的所有服務都可以放入Jersey(或任何其他ServiceLocator)的ServiceLocator中。 這是API: bridgeServiceLocator 。 它位於hk2的hk2-extras模塊中。
在hk2 2.4.0-b10中有一個版本可以使用,完全測試和記錄的功能將在hk2 2.4.0-b11
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.