Java 如何在Jersey 2中禁用依赖项注入?

Java 如何在Jersey 2中禁用依赖项注入?,java,jersey,guice,jersey-2.0,hk2,Java,Jersey,Guice,Jersey 2.0,Hk2,我不熟悉用Jersey 2创建REST web服务。我有几个简单的案例,现在我开始“真正”的工作 我创建自己的ResourceConfig实例,并用Guice返回的REST控制器实例填充ResourceConfig实例: <!-- language: lang-java --> final ResourceConfig rc = new ResourceConfig(); //register an *instance* of a REST controller rc.regist

我不熟悉用Jersey 2创建REST web服务。我有几个简单的案例,现在我开始“真正”的工作

我创建自己的
ResourceConfig
实例,并用Guice返回的REST控制器实例填充
ResourceConfig
实例:

<!-- language: lang-java -->
final ResourceConfig rc = new ResourceConfig();

//register an *instance* of a REST controller
rc.register(injector.getInstance(MyRestController.class));
显然,Jersey正在尝试解析REST控制器实例上的
@Inject
依赖项,因为它看到与Guice相同的
@Inject
注释

我不想Jersey做任何依赖注入。我认为从Jersey到Guice之间有桥梁,但是基于我在这里无法展示的程序需求,我需要自己创建REST控制器实例,并向Guice
Injector
询问它们

我的问题:如何在Jersey中禁用依赖注入

我目前正在使用
javax.inject.inject
注释。也许我可以使用
com.google.inject.inject
注释来代替,因为我认为Jersey不会寻找这些注释。但是,我还是宁愿在泽西岛关闭依赖注入。我该怎么做

谢谢

首先,您的解决方案:

public class GuiceJerseyManualBridge extends io.dropwizard.Application<Configuration> {

    @Override
    public void run(Configuration configuration, Environment environment) throws Exception {
        JerseyEnvironment jersey = environment.jersey();

        // create the Guice env and its dependencies
        Injector i = Guice.createInjector(new AbstractModule() {
            @Override
            protected void configure() {
                Map<String, String> props = new HashMap<>();
                props.put("testme", "Hello World Guice Inject Test");
                Names.bindProperties(binder(), props);
                bind(HelloResource.class).in(Singleton.class);
            }
        });

        // get instance

        HelloResource resourceInstance = i.getInstance(HelloResource.class);
        jersey.register(new AbstractBinder() {

            @Override
            protected void configure() {
                // teach jersey about your guice dependency 
                bind(resourceInstance).to(HelloResource.class);
            }
        });

        jersey.register(HelloResource.class); // register resource - jersey will discover this from the binding
    }

    @Override
    public void initialize(Bootstrap<Configuration> bootstrap) {
        super.initialize(bootstrap);
    }

    public static void main(String[] args) throws Exception {
        new GuiceJerseyManualBridge().run("server", "/home/artur/dev/repo/sandbox/src/main/resources/config/test2.yaml");
    }

    @Path("test")
    @Produces(MediaType.APPLICATION_JSON)
    public static class HelloResource {


        @Inject
        @Named("testme")
        private String testString;

        public HelloResource() {
            System.err.println("I am created now");
        }

        @GET
        @Path("test")
        public String test(String x) {
            return testString;
        }

    }

}
public类GuiceJerseyManualBridge扩展io.dropwizard.Application{
@凌驾
公共void运行(配置、环境)引发异常{
JerseyEnvironment jersey=environment.jersey();
//创建Guice env及其依赖项
Injector i=Guice.createInjector(新的AbstractModule(){
@凌驾
受保护的void configure(){
Map props=newhashmap();
put(“testme”、“helloworld Guice注入测试”);
name.bindProperties(binder(),props);
bind(HelloResource.class).in(Singleton.class);
}
});
//获取实例
HelloResource resourceInstance=i.getInstance(HelloResource.class);
泽西岛。登记册(纽约){
@凌驾
受保护的void configure(){
//教jersey关于您的guice依赖性
绑定(resourceInstance.to)(HelloResource.class);
}
});
jersey.register(HelloResource.class);//注册资源-jersey将从绑定中发现这一点
}
@凌驾
公共无效初始化(引导引导引导){
初始化(引导);
}
公共静态void main(字符串[]args)引发异常{
新的GuiceJerseyManualBridge().run(“server”,“/home/artur/dev/repo/sandbox/src/main/resources/config/test2.yaml”);
}
@路径(“测试”)
@产生(MediaType.APPLICATION_JSON)
公共静态类HelloResource{
@注入
@命名(“testme”)
私有字符串testString;
公共HelloResource(){
System.err.println(“我现在被创建”);
}
@得到
@路径(“测试”)
公共字符串测试(字符串x){
返回testString;
}
}
}
请忽略我的DropWizard设置。它使用Jersey和Guice,所以注册部分是相同的

您在这里面临两个困境:

  • Jersey DI将尝试在对象中注入字段。这是因为它没有意识到有一个已经完成的目标。它假定必须注入字段 因此,我上面的解决方案执行以下操作:

    将guicebean绑定到jersey环境。这将使jersey能够找到您创建的bean。由于它被绑定到jersey env中,因此它不会尝试重新初始化bean,而是将其视为完全有效的对象。 为此,您需要将资源注册为类参数(搜索已注册的bean,或者根据需要创建一个bean)

    您可以做的另一个解决方案是将注入移动到构造函数(通常是避免字段注入的良好实践)。因为您注册了一个对象,所以再次调用构造函数是非法的。因此,泽西不会尝试进行任何注射(因为无需进行注射)

    最后,我不知道您的需求是如何工作的,但您想要做的基本上是手动创建一个Guice Jersey桥。以您演示的方式向jersey教授bean正是Guice jersey bridge所做的,唯一的例外是它修复了所有这些小边缘情况(正如您现在看到的)。强烈建议您实现该桥

    该桥真正做的是将bean的创建委托给guice。这意味着它将(1)向guice请求一个实例,然后自己创建一个(如果guice不返回实例)

    希望有帮助


    干杯!阿图尔

    这成功了,谢谢!!对于那些阅读者,我的一个快速技巧是使用
    com.google.inject.inject
    注释,而不是标准的
    javax.inject.inject
    注释。然而,我仍然想要一个基于新泽西的解决方案。在我的特殊情况下,上面代码中的
    JerseyEnvironment
    实际上是
    ResourceConfig
    的一个实例,但是所有必要的方法都存在。奇怪的是,泽西没有禁用DI的开关。同样奇怪的是,一个类绑定到一个实例;通常情况下是相反的。不管怎样,谢谢你!!这对匕首有什么作用?
    public class GuiceJerseyManualBridge extends io.dropwizard.Application<Configuration> {
    
        @Override
        public void run(Configuration configuration, Environment environment) throws Exception {
            JerseyEnvironment jersey = environment.jersey();
    
            // create the Guice env and its dependencies
            Injector i = Guice.createInjector(new AbstractModule() {
                @Override
                protected void configure() {
                    Map<String, String> props = new HashMap<>();
                    props.put("testme", "Hello World Guice Inject Test");
                    Names.bindProperties(binder(), props);
                    bind(HelloResource.class).in(Singleton.class);
                }
            });
    
            // get instance
    
            HelloResource resourceInstance = i.getInstance(HelloResource.class);
            jersey.register(new AbstractBinder() {
    
                @Override
                protected void configure() {
                    // teach jersey about your guice dependency 
                    bind(resourceInstance).to(HelloResource.class);
                }
            });
    
            jersey.register(HelloResource.class); // register resource - jersey will discover this from the binding
        }
    
        @Override
        public void initialize(Bootstrap<Configuration> bootstrap) {
            super.initialize(bootstrap);
        }
    
        public static void main(String[] args) throws Exception {
            new GuiceJerseyManualBridge().run("server", "/home/artur/dev/repo/sandbox/src/main/resources/config/test2.yaml");
        }
    
        @Path("test")
        @Produces(MediaType.APPLICATION_JSON)
        public static class HelloResource {
    
    
            @Inject
            @Named("testme")
            private String testString;
    
            public HelloResource() {
                System.err.println("I am created now");
            }
    
            @GET
            @Path("test")
            public String test(String x) {
                return testString;
            }
    
        }
    
    }