如何在Jersey2 ServletContainer中获取HK2 ServiceLocator?

Lau*_*ire 4 guice jersey-2.0 hk2

我想让Jersey2和Guice一起合作,这显然是相当困难的.我已经看到了一些涉及使用HK2-to-Guice桥的解决方案.但是这个桥依赖于ServiceLocatorinit()自定义Jersey2 ServletContainer中获取HK2 实例以便初始化GuiceBrige:

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

但不知何故,在泽西岛(2.26)的最后版本中,getServiceLocator()不再存在ApplicationHandler.我怎样才能在这种情况下得到它?

Pau*_*tha 11

免责声明:我不使用Guice,所以这不是我测试过的.所以我不知道OP正在尝试做什么甚至可以工作.我只是回答了如何获取ServiceLocator的主要问题.


正如提到我的评论在这里,起2.26,泽西不再有上HK2依赖.因此,在整个代码库中,您将不再看到对a的引用ServiceLocator,而是更高级别的引用InjectionManager.它InjectionManager具有与之相同的目的ServiceLocator,但是抽象允许依赖注入提供者的不同实现.这就是为什么在使用2.26时,我们需要添加jersey-hk2依赖项.这是HK2的实施InjectionManager.在此实现中,InjectionManager将简单地将调用委托给底层ServiceLocator.

话虽这么说,ApplicationHandler让你访问InjectionManager现在,而不是ServiceLocator.它ServiceLocator本身就是一种服务,所以如果你有一个定位器,你可以做到以下(这是毫无意义的,但它只是表明了我的观点)

ServiceLocator locator = getServiceLocator();
locator = locator.getService(ServiceLocator.class);
Run Code Online (Sandbox Code Playgroud)

这意味着您也可以从中获取定位器InjectionManager,它只是底层定位器的高级委托者

InjectionManager im = getApplicationHandler().getInjectionManager();
ServiceLocator locator = im.getInstance(ServiceLocator.class);
Run Code Online (Sandbox Code Playgroud)

需要指出的一件事是,我的免责声明的主要原因是你需要super.init() 在你的init()方法中打电话,否则当你试图获得时,你会得到一个NPE ApplicationHandler.这个问题是有很多初始化完成; 几乎整个应用程序都已初始化.因此,尝试添加Guice集成可能会或可能不会太晚.

以下是我看到过这种集成的其他地方.而且我相信在你试图做到这一点之前,他们都会受到打击init().

  • ResourceConfig构造函数中,您可以注入InjectionManager.
  • 在一个Feature你可以InjectionManager通过InjectionManagerProvider静态方法的地方.
  • 我没有看到任何实现这个,但我认为做桥的首选位置是在文档中ComponentProvider提到.我见过的唯一一个实现是Spring.您可以在jersey-spring4中看到来源.这可能需要更多工作,但我认为这将是最合适的位置,因为它在所有其他先前选项之前被调用.可能不需要它,因为我已经看到其他人可以选择其他两个选项.