2016-09-13 1 views
8

I created a project Resteasyを使用して、Jax-rsのリソースでGoogle Guiceが提供する依存性注入をテストします。ResteasyとGoogle Guice:@Injectionで複数の@ApplicationPathとリソースを使用する方法は?

私の意図は、次のとおりです。私のAPIのバージョンの

  • 使用し、複数の@ApplicationPath@ApplicationPathで注釈が付けられた各クラスでは、特定のバージョンのクラスのセットを読み込みます。
  • 各リソースには、サービスを注入するコンストラクタ内に@Inject(Google Guiceから)があります。

@ApplicationPathApplicationV1RSApplicationV2RSという2つのクラスを作成しました。両方とも私は同じリソースクラス(UserResourceHelloResource)を私のテストのためだけに追加しました。

私のモジュールは、次のように設定されている:私はhttp://localhost:9095/v1/hello/worldまたはhttp://localhost:9095/v2/hello/world呼び出すと

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); 
    } 
} 

、私は同じエラーが表示されます。

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

、私は予想通り、これはない作品。 Google Guiceは、私のためにconstrutorを使ってリソースクラスをインスタンス化する "スマート"ではありません。

しかし、私は働く方法を見つけることができません。本当に正直なところ、このシナリオでGoogle Guice、Jetty、Resteasyがどう対戦するかは本当に混乱しています。

私が使用@ApplicationPathの考えを放棄した場合、私のリソースは、このように私のHelloModuleを設定するGoogleのGuiceのでは動作:

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); 
    } 
} 

しかし、この場合には、私は私のリソースを登録するために制御を渡している(HelloResourceUserResource)をGuiceに送信します。それは私のために柔軟ではない、私は複数の@ApplicationPathを設定することはできません。

だから私は迷っているか、理解していないのですか?

問題のあるコードでプロジェクトを作成しました。セットアップとテストが非常に簡単です:https://github.com/dherik/resteasy-guice-hello/tree/so-question/README.md

ありがとう!

答えて

1

アプリケーションにメソッドがあると、リソースクラスにない既定のコンストラクターを使用して、登録済みのすべてのリソースのインスタンスを作成しようとします。 1つの方法は、デフォルトのコンストラクタを作成し、セッター注入を使用して依存関係を注入することです。 getClassesApplicationV1RSApplicationV2RSに上書きする代わりに、getSingletonsを上書きします。リソースはシングルトンになることができるからです。

以下は、私が望むように動作させるために加えた変更です。

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にプッシュしました。それをチェックしてください

+0

web.xmlはまだ必要ありませんか?私は正しい? – SayusiAndo

関連する問題