Jersey - Is there a way to instantiate a Per-Reque

2019-05-07 05:26发布

问题:

Suppose I have this class:

@Path("/test")
public class TestResource{

   private TestService testService;

   public TestResource(TestService testService){
      this.testService = testService;
   }

   @GET
   public String getMessage(){
      return testService.getMessage();
   }


}

Then, I want to register it with Jersey. One would do:

 TestService testService = new TestServiceImpl();
 resourceConfig.register(new TestResource(testService));

But the problem is that approach makes a single instance of TestResource. I want to make an instance per request. So, Jersey has a way of doing this:

 TestService = new TestServiceImpl();
 resourceConfig.register(TestResource.class);

That is great! But it doesn't let me to pass instantiation parameters to its constructor.

On top of this, I'm using DropWizard which also doesn't let me access all the methods from the ResourceConfig (but I checked its documentation and didn't find any method that let me pass parameters)

So I was wondering if there is a way of achieving this.

Thanks!

PS: I know I can get away with this using Spring or Guice (or my own instance provider) and injecting my classes, but I don't want to do that (of course I'll do it if it's the only way)

回答1:

As @peeskillet has mentioned, jersey 2.x is tightly coupled with HK2 and it seems that it's the only way to pass a service to it.

@Singleton
@Path("/test")
public class TestResource {

   private TestService testService;

   @Inject
   public TestResource(TestService testService){
      this.testService = testService;
   }

   @GET
   public String getMessage(){
      return testService.getMessage();
   }
}

And this is how you register:

environment.jersey().register(new AbstractBinder(){
   @Override
   protected void configure() {
      bind(TestServiceImpl.class).to(TestService.class);
      // or
      bind(new TestServiceImpl()).to(TestService.class);
   });
environment.jersey().register(TestResource.class);