我created a project使用Resteasy测试Google Guice在我的Jax-rs资源中提供的依赖注入。
我的意图是:
@ApplicationPath
。在每个用@ApplicationPath
注释的类中,我为特定版本加载了一组类。 @Inject
(来自Google Guice)以注入一些服务。我创建了两个使用@ApplicationPath
注释的类:ApplicationV1RS
和ApplicationV2RS
。在两者中,我添加了相同的资源类(UserResource
和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
或http://localhost:9095/v2/hello/world
时,我收到同样的错误:
java.lang.RuntimeException: RESTEASY003190: Could not find constructor
for class: org.jboss.resteasy.examples.guice.hello.HelloResource
好吧,正如我所料,这不起作用。对于我来说,使用construtor实例化资源类并不是“聪明”的。
但我找不到办法。说实话,我真的很困惑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
和UserResource
)注册到Guice。它对我来说不灵活,我无法设置我的多个@ApplicationPath
。
那么,我缺少什么或不理解?
我用问题代码创建了一个项目。设置和测试非常简单:https://github.com/dherik/resteasy-guice-hello/tree/so-question/README.md
谢谢!
答案 0 :(得分:1)
当你的应用程序中有getClasses
方法时,它会尝试使用我们的Resources类中缺少的默认构造函数为所有已注册的资源创建实例。一种方法是创建默认构造函数并通过setter Injection注入依赖项。
然后,不要覆盖ApplicationV1RS
和ApplicationV2RS
中的getSingletons
,而是覆盖@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;
}
}
。由于资源可以是Singleton。
以下是我为使其按您想要的方式所做的更改。
ApplicationV1RS.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;
}
}
ApplicationV2RS.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);
}
}
HelloResource.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);
}
}
UserResource.java
@Singleton
将{{1}}添加到您的服务类。
希望它有所帮助。
我还将代码推送到forked repo。检查出来