Jersey 泽西岛和HK2服务定位器

Jersey 泽西岛和HK2服务定位器,jersey,hk2,Jersey,Hk2,我试图在应用程序构造函数(从ResourceConfig继承的东西)中初始化Jersey应用程序中的一些组件。看起来像这样 public Application(@Context ServletContext context, @Context ServiceLocator locator)... 当我试图在任何时候使用定位器时,我仍然无法使用locator.create(MyThing.class)方法创建我在AbstractBinder中注册的东西的实

我试图在应用程序构造函数(从ResourceConfig继承的东西)中初始化Jersey应用程序中的一些组件。看起来像这样

public Application(@Context ServletContext context,
                   @Context ServiceLocator locator)...
当我试图在任何时候使用定位器时,我仍然无法使用locator.create(MyThing.class)方法创建我在AbstractBinder中注册的东西的实例

我确信它们是正确绑定的,因为它们是通过@injectfield注释正确地注入到我的资源类中的

区别在于Jersey/HK2框架正在实例化我的资源类(正如预期的那样,因为它们位于我的包扫描路径中),但我似乎无法通过代码利用ServiceLocator

我的最终目标是在其他非jersey类具有@Inject属性时注入它们,例如,我有一个需要注入配置的数据库访问层的worker类。我想说

locator.Create(AWorker.class) 
然后注射


我如何获得真正的ServiceLocator,它将注入我已经注册/绑定到活页夹的所有内容?(或者我应该使用ServiceLocator以外的其他工具吗?

您如何启动您的容器?如果您使用的是ApplicationHandler,则只需调用:
handler.getServiceLocator()
。实际上,ServiceLocator是您想要用来访问依赖项的工具

如果要启动servlet,我发现访问服务定位器的最佳方法是在我的启动类上设置Jersey特性:

    private static final class LocatorSetFeature implements Feature {

    private final ServiceLocator scopedLocator;

    @Inject
    private LocatorSetFeature(ServiceLocator scopedLocator) {
        this.scopedLocator = scopedLocator;
    }

    @Override
    public boolean configure(FeatureContext context) {
        locator = this.scopedLocator; // this would set our member locator variable
        return true;
    }
}
该特性将仅通过config.register(new LocatorSetFeature())在资源配置中注册


根据容器的生命周期来连接其他组件的启动是很重要的,所以这仍然让人感觉有点不舒服。您可以考虑将这些类添加为HK2容器中的第一类依赖项,并简单地将适当的依赖项注入到第三方类中(例如使用绑定器)。。如果随后要访问ServiceLocator以执行其他初始化,则有两种选择:

一种方法是注册ContainerLifecycleListener(如下所示):

第二种方法是使用
功能,也可以使用
@Provider
自动发现该功能:

@Provider
public final class StartupListener implements Feature {

    private final ServiceLocator sl;

    @Inject
    public ProvisionStartupListener(final ServiceLocator sl) {
        this.sl = sl;
    }

    @Override
    public boolean configure(final FeatureContext context) {
        // Perform whatever action with serviceLocator
        return true;
    }

我认为您不能在
应用程序中充分利用hk2。该应用程序提供有关如何设置Jersey的信息。还应告知您与球衣相关的hk2活页夹。只要此绑定没有发生,就无法通过服务定位器使用。我正在注册我的绑定,然后再尝试访问定位器。仍然不确定我应该做什么=你敢肯定绑定器不仅被注册了,而且还绑定了它的实例吗?我不明白这个问题,但是我的绑定器确实绑定了(Concrete.Class)。在configure()方法中绑定到(Interface.Class)。使用locator.create不需要正在创建的东西已经注册到HK2。它将尝试继续并创建给定类的实例。此外,MyThing.class将不由HK2管理,因此无法进一步注入其他内容。如果类“MyThing.class”使用构造函数注入,那么当然需要在ServiceLocator中找到构造函数所需的服务。也许您应该发布从locator.create(MyThing.class)以及MyThing.class代码的相关部分获得的异常。您包含的代码未编译:locator=scopedLocator未编译,因为未定义定位器,此变量在哪里?请提供更正。
@Provider
public final class StartupListener implements Feature {

    private final ServiceLocator sl;

    @Inject
    public ProvisionStartupListener(final ServiceLocator sl) {
        this.sl = sl;
    }

    @Override
    public boolean configure(final FeatureContext context) {
        // Perform whatever action with serviceLocator
        return true;
    }