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

2023-11-26

I 创建了一个项目使用 Resteasy 在我的 Jax-rs 资源中测试 Google Guice 提供的依赖项注入。

我的意图是:

  • 使用多个@ApplicationPath对于我的 API 的版本。在每个类中注释为@ApplicationPath我为特定版本加载一组类。
  • 每个资源都有一个@Inject(来自 Google Guice)在他的构造函数中注入一些服务。

我创建了两个带有注释的类@ApplicationPath: ApplicationV1RS and ApplicationV2RS。在这两个中我都添加了相同的资源类(UserResource and HelloResource),仅用于我的测试。

我的模块配置如下:

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/world or http://localhost:9095/v2/hello/world,我收到同样的错误:

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

嗯,正如我所料,这不起作用。 Google Guice 并不“聪明”地使用构造函数实例化资源类。

但我找不到工作的方法。说实话,我真的很困惑 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);
   }
}

但在这种情况下,我将传递控制权来注册我的资源(HelloResource and UserResource)到吉斯。这对我来说不灵活,我无法设置我的多个@ApplicationPath.

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

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

Thanks!


当你有getClasses方法,然后它尝试使用我们的 Resources 类中缺少的默认构造函数为所有注册资源创建实例。一种方法是创建默认构造函数并通过 setter 注入注入依赖项。 然后而不是覆盖getClasses in ApplicationV1RS and ApplicationV2RS你覆盖getSingletons。由于资源可以是单例的。

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

应用程序V1RS.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;
    }
}

应用程序V2RS.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);
    }
}

用户资源.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);
    }
}

Add @Singleton到您的服务等级。

希望能帮助到你。

我也将代码推送到分叉回购协议。一探究竟

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Resteasy 和 Google Guice:如何通过 @Injection 使用多个 @ApplicationPath 和资源? 的相关文章

随机推荐