【问题标题】:Jersey 2.26+: configure() not called after converting HK2's Factory to SupplierJersey 2.26+:将 HK2 的工厂转换为供应商后未调用 configure()
【发布时间】:2021-07-17 13:05:42
【问题描述】:

为了简化我们的网络服务,我想在 2.34 版本中使用 Jersey 框架引入一个自定义的 MyObj 类,并希望通过 @Context 注入创建的实例注释。

我有两个问题:

  1. 假设一个 web 服务方法 @GET test(@Context MyObj obj),我如何控制 when MyObj 的实例在关于现有 servlet 请求过滤器的执行?

  2. 要创建 MyObj 的实例,我已经有了一个基于 HK2 的 Factory 的工作示例(见下文)。由于我观察到我的工厂类被实例化了两次,并且 Jersey 2.26+ 建议使用基于 Supplier 的新方法,因此我尝试转换我的示例。不幸的是,在提供的 Binder 实现 Supplier 类中不会调用 configure(),因此不会创建任何对象。我怎样才能得到这个工作? (顺便说一句,在这两种情况下,BinderBinderHK 都是通过 jersey.config.server.provider.classnames 在我的 web 中注册的.xml。)

感谢您的帮助。

工作中的 HK2 工厂示例:

public class MyObjHK {}

import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.process.internal.RequestScoped;
public class BinderHK
extends AbstractBinder {
    @Override protected void configure() {
        bindFactory(MyObjFactoryHK.class).to(MyObjHK.class).in(RequestScoped.class);
    }
}

import org.glassfish.hk2.api.Factory;
public class MyObjFactoryHK
implements Factory<MyObjHK> {
    @Override public MyObjHK provide() {return new MyObjHK();} // ok
    @Override public void dispose(MyObjHK instance) {};
}

public class API_HK2 {
    @GET
    public static Response myobjhk(@Context MyObjHK obj) {
        System.out.println("called hk, obj="+obj); // ok
        return Response.ok().build();
    }
}

不工作的供应商示例:

public class MyObj {}

import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.process.internal.RequestScoped;
public class Binder
extends AbstractBinder {
    @Override protected void configure() { // not called ???
        bindFactory(MyObjFactory.class).to(MyObj.class).in(RequestScoped.class);
    }
}

import java.util.function.Supplier;
public class MyObjFactory
implements Supplier<MyObj> { 
    @Override public MyObj get() {return new MyObj();}
}

public class API {
    @GET
    public static Response myobj(@Context MyObj obj) {
        System.out.println("called, obj="+obj); // null ???
        return Response.ok().build();
    }
}

【问题讨论】:

    标签: java jersey migration code-injection


    【解决方案1】:

    活页夹不是可以使用jersey.config..classnames init-param 注册的东西。您需要使用 ResourceConfigFeature 注册它(并使用 init-param 注册功能)

    @Provider
    public class MyFeature implements Feature {
        @Override
        pubic boolean configure(FeatureContext ctx) {
            ctx.register(new MyBinder());
            return true;
        }
    }
    

    【讨论】:

    • 谢谢,但 MyFeature/Binder 方法对我也不起作用(我尝试使用 init-param jersey.config.server.provider.classnames 以及 jersey.config.server.provider 进行注册。与@Provider 一起打包)。此外,与您的说法相反,即使不使用功能,注册 BinderHK extends AbstractBinder (请参阅下面的工作示例)也可以工作。欢迎提供更多提示。
    • eclipse-ee4j.github.io/jersey.github.io/documentation/latest/…,第24.1章的例子中,直接注册了一个AbstractBinder的实现。它与解释相匹配:“虽然各个注入绑定实现会有所不同并取决于您的用例,但要在 Jersey 中启用您的自定义注入扩展,您必须在您的应用程序 ResourceConfig 中注册您的自定义 HK2 Binder 实现!”。现在,我想知道 web.xml 是否还不够,但我真的必须明确使用 ResourceConfig 实例(我还没有测试过)?
    • 该文档已多年未更新。特别是关于HK2。如您所见,它仍然使用 HK2,尽管这不再是推荐的用法。除非您特别需要 HK2 功能,否则您所有的注入导入都应该来自 jersey.internal.inject 包。
    • 好的,在设置一个完整的示例时,我显然发现了问题。我不小心用 @Provider 注释了 AbstractBinderFeature 类。删除 AbstractBinder 类中的注释并将其仅保留在 Feature 类中(根据您的回答),问题就消失了。感谢您的支持。我有最后一个问题:我仍然必须保持 org.glassfish.jersey.inject - jersey-hk2 依赖项(在 pom.xml 中的 2.34 版本中)以保持工作正常吗?
    猜你喜欢
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多