2016-09-13 21 views
8

I created a project.Resteasy ve Google Guice: @Injection ile çoklu @UygulamaPath ve kaynak nasıl kullanılır? Google Guice tarafından sunulan bağımlılık enjeksiyonunu Jax-rs kaynaklarımda Resteasy kullanarak test etmek için

Niyetim şunlardır: benim API sürümleri için

  • Kullanım birden @ApplicationPath. @ApplicationPath ile açıklanmış her sınıfta, belirli bir sürüm için bir grup sınıf yüklüyorum.
  • Her kaynağın, bazı hizmetleri enjekte etmesi için yapıcısında @Inject (Google Guice'den) var. ApplicationV1RS ve ApplicationV2RS:

Ben @ApplicationPath ile açıklamalı iki ayrı sınıf yarattılar. Her ikisinde de sadece testlerim için aynı kaynak sınıflarını (UserResource ve HelloResource) ekledim.

My Modülü böyle yapılandırılır:

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

Ben http://localhost:9095/v1/hello/world veya http://localhost:9095/v2/hello/world diyoruz

, ben aynı hatayı alırsınız:

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

Peki, beklediğim gibi, bu değil işleri. Google Guice, kaynak sınıflarını benim için yapıcıyı kullanarak başlatmak için "akıllı" değildir.

Ama çalışmanın bir yolunu bulamıyorum. Gerçekten dürüst olmak gerekirse, Google Guice, Jetty ve Resteasy'nin bu senaryoda birbirleriyle nasıl oynandığını gerçekten karıştırıyorum. Ben kullanım @ApplicationPath fikri terk ederse

, benim kaynakları hakkında Guice böyle benim HelloModule yapılandırarak çalışmak:

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

Ama bu durumda

, ben ( HelloResource Kaynaklarımı kayıt kontrolünü geçiyorum ve UserResource) Guice'ye. Benim için esnek değil, çoklu @ApplicationPath'u ayarlayamıyorum.

Peki, ne eksik veya anlamadığım?

Sorunlu kod ile bir proje oluşturdum. Kurulumu ve testi çok kolaydır: https://github.com/dherik/resteasy-guice-hello/tree/so-question/README.md

Teşekkürler!

cevap

1

Uygulamanızda getClasses yöntemine sahip olduğunuzda, Kaynak sınıfımızda eksik olan varsayılan kurucuyu kullanarak tüm kayıtlı kaynaklar için örnek oluşturmaya çalışır. Bir yol, varsayılan bir kurucu oluşturmak ve Bağımlılığı Enjektör ile enjekte etmektir. Ve sonra getClasses'u ApplicationV1RS ve ApplicationV2RS'da geçersiz kılmak yerine getSingletons'u geçersiz kılarsınız. Kaynaklar Singleton olabileceğinden.

Aşağıda, istediğiniz şekilde çalışmasını sağlamak için yaptığım değişiklikler var.

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

Servis Sınıflarına @Singleton ekle

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

ApplicationV1RS.java

.

Yardım edin.

Ayrıca kodu forked repo'a da ittim. Bunu kontrol et

+0

Ve web.xml hala gerekli değil? Ben haklı mıyım – SayusiAndo

İlgili konular