4

This question is regarding the sample: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-jersey/src/main/java/sample/jersey/Endpoint.java

Why do we need "@Component" annotation for Jersey resource when using spring-boot -starter-jersey project?

If I remove it, the Jersey servlet can still serve resources.

So what is the need for "@Component"?

Jothi
  • 511
  • 1
  • 5
  • 9
  • As soon as you want to inject other Spring components, the resource has also to be a Spring component. – dunni Jun 30 '16 at 21:50

2 Answers2

3

You don't need it. Jersey uses HK2 as it's internal DI framework, and HK2 has a Spring bridge. This is what's used internally to bridge Spring components into the HK2 IoC container, so that they can be injected into Jersey components. And Jersey implements an AutowiredInjectionResolver1 that allows for injection of Spring components using @Autowired. You don't even need @Autowired though. All the Spring components can be injected with the normal @Inject.

The only drawback I've ran into, not making the Jersey components a Spring @Component is that it doesn't support @Value when you want to inject property values.

The one thing I don't like is that when you declare something a Spring @Component, it automatically makes it a singleton. But Jersey resources are by default request scoped. You can add a Spring @Scope("request"), and it should change the resource to a request scoped resource. Jersey has declared the Spring RequestScope, so we can use it. How exactly it ties in to Jersey's request scope, I am not a hundred percent sure. I ran into a problem a while back. I can't remember what it was, but that has kept me from ever using the Spring request scope again.

Assuming I want to keep all my resources request scoped, I would take sticking to the normal Jersey request scope, and not being able to inject @Values, over having to use Spring's request scope. Maybe I'm imagining things, and there was no issue using it, but personally I'll just stick to what I know works :-)

UPDATE

Another thing that does't work if you don't make the resource a Spring @Component is Spring's AOP. That's fine with me though as HK2 also has AOP.


1 - An InjectionResolver allows you to use custom annotations to create injection targets.

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
0

When you remove @Component jersey takes control of the scope of the instance. With @Component a singleton instance is created, removing it you can use the following jersey annotations:

• Request scope (Default): By using the @RequestScope annotation or none, we can have a life-cycle till the request lasts. This is the default scope of the root-resource classes. For each new request, a new root-resource instance is being created and served accordingly for the first time. However, when the same root-resource method is being called, then the old instance will be used to serve the request.

• Per-lookup scope: The @PerLookup annotation creates root-resource instances for every request.

• Singleton: The @Singleton annotation allows us to create only a single instance throughout the application.


Try different behaviors using a counter inside your class...

public class MyWebResource {
private int counter;

@GET
@Path("/counter")
@Produces(MediaType.APPLICATION_JSON)
public Response getCounter() {
    counter++;
    return Response.status(Status.OK).entity(counter).build();
}

}
barrenaedu
  • 19
  • 2