Resteasy 和 Google Guice:如何通过 @Injection 使用多个 @ApplicationPath 和资源?

Resteasy and Google Guice: how to use multiple @ApplicationPath and resource with @Injection?

created a project 使用 Resteasy 在我的 Jax-rs 资源中测试 Google Guice 提供的依赖注入。

我的意图是:

我创建了两个用 @ApplicationPath 注释的 class:ApplicationV1RSApplicationV2RS。我在两者中都添加了相同的资源 classes(UserResourceHelloResource),仅用于我的测试。

我的模块是这样配置的:

public class HelloModule implements Module
{
   public void configure(final Binder binder)
   {
      binder.bind(IGreeterService.class).to(GreeterService.class);

      binder.bind(IUserService.class).to(UserService.class);
   }
}

当我调用 http://localhost:9095/v1/hello/worldhttp://localhost:9095/v2/hello/world 时,我收到相同的错误:

java.lang.RuntimeException: RESTEASY003190: Could not find constructor 
    for class: org.jboss.resteasy.examples.guice.hello.HelloResource

好吧,如我所料,这行不通。 Google Guice 不是 "smart" 为我使用构造器实例化资源 classes。

但是我找不到工作的方法。老实说,我真的很困惑 Google Guice、Jetty 和 Resteasy 在这种情况下如何相互配合。

如果我放弃使用 @ApplicationPath 的想法,我的资源将使用 Google Guice 配置我的 HelloModule,如下所示:

public class HelloModule implements Module
{
   public void configure(final Binder binder)
   {
      binder.bind(HelloResource.class);
      binder.bind(IGreeterService.class).to(GreeterService.class);

      binder.bind(UserResource.class);
      binder.bind(IUserService.class).to(UserService.class);
   }
}

但在这种情况下,我将控制权传递给 Guice 来注册我的资源(HelloResourceUserResource)。它对我来说不灵活,我无法设置我的倍数 @ApplicationPath.

那么,我缺少或不理解的是什么?

我用有问题的代码创建了一个项目。非常容易设置和测试:https://github.com/dherik/resteasy-guice-hello/tree/so-question/README.md

谢谢!

当您的应用程序中有 getClasses 方法时,它会尝试使用我们的资源 class 中缺少的默认构造函数为所有已注册资源创建实例。一种方法是创建默认构造函数并通过 setter 注入来注入依赖项。 然后在 ApplicationV1RSApplicationV2RS 中覆盖 getClasses 而不是覆盖 getSingletons。由于 Resources 可以是 Singleton。

以下是我为使其按照您想要的方式工作而进行的更改。

ApplicationV1RS.java

@ApplicationPath("v1")
public class ApplicationV1RS extends Application {

    private Set<Object> singletons = new HashSet<Object>();

    public ApplicationV1RS(@Context ServletContext servletContext) {
    }

    @Override
    public Set<Object> getSingletons() {
        Injector injector = Guice.createInjector(new HelloModule());

        HelloResource helloResource = injector.getInstance(HelloResource.class);
        UserResource userResource = injector.getInstance(UserResource.class);
        singletons.add(helloResource);
        singletons.add(userResource);
        return singletons;
    }
}

ApplicationV2RS.java

@ApplicationPath("v2")
public class ApplicationV2RS extends Application {

    private Set<Object> singletons = new HashSet<Object>();

    public ApplicationV2RS(@Context ServletContext servletContext) {
    }

    @Override
    public Set<Object> getSingletons() {
        Injector injector = Guice.createInjector(new HelloModule());

        HelloResource helloResource = injector.getInstance(HelloResource.class);
        UserResource userResource = injector.getInstance(UserResource.class);
        singletons.add(helloResource);
        singletons.add(userResource);
        return singletons;
    }
}

HelloResource.java

@Path("hello")
public class HelloResource {
    @Inject
    private IGreeterService greeter;

    public HelloResource() {
    }

    @GET
    @Path("{name}")
    public String hello(@PathParam("name") final String name) {
        return greeter.greet(name);
    }
}

UserResource.java

@Path("user")
public class UserResource {

    @Inject
    private IUserService userService;

    public UserResource() {
    }

    @GET
    @Path("{name}")
    public String hello(@PathParam("name") final String name) {
        return userService.getUser(name);
    }
}

@Singleton 添加到您的服务 类。

希望对您有所帮助。

我也把代码推到了forked repo。看看