spring-bootjerseyspring-jersey

Using Jersey with Spring Boot


The Spring Boot Reference Documentation in section titled 7.3 JAX-RS and Jersey mentions "All the registered endpoints should be @Components with HTTP resource annotations (@GET and others). Since the Endpoint is a Spring @Component, its lifecycle is managed by Spring and you can use the @Autowired annotation to inject dependencies and use the @Value annotation to inject external configuration".

But I don't care to have dependencies injected or external configuration injected into my Jersey resources and hence I did not annotate my Jersey resources as @Components. My app works just fine.

From reading the Spring Boot Reference Documentation, it seemed that registering Jersey resources as @Components was a requirement. But that does not seem to be the case. To me this seems like a small bug in the Spring Boot Reference Documentation. May be the documentation can be updated from "registered endpoints should be @Components" to "registered endpoints can be @Components". Does this make sense?


Solution

  • I did try this out and found that annotating a Jersey resource with the the Spring @Component annotation is optional. Should you use that annotation then the resource's life-cycle will be managed by Spring and if you do NOT use that annotation then the life-cycle will be managed by Jersey.

    One important thing to note is that there is major difference in how that life-cycle is programmed by default between the two.

    As stated in section 3.4 of the Jersey User Guide "By default the life-cycle of root resource classes is per-request which, namely that a new instance of a root resource class is created every time the request URI path matches the root resource. This makes for a very natural programming model where constructors and fields can be utilized without concern for multiple concurrent requests to the same resource. In general this is unlikely to be a cause of performance issues. Class construction and garbage collection of JVMs has vastly improved over the years and many objects will be created and discarded to serve and process the HTTP request and return the HTTP response."

    But as stated in the Spring Framework Documentation section 1.5 ; beans by default are singleton. "Spring IoC container creates exactly one instance of the object defined by that bean definition. This single instance is stored in a cache of such singleton beans, and all subsequent requests and references for that named bean return the cached object."

    Hence there is a difference. Normal Jersey root resource classes by default are instantiated per-request, while with Spring when a resource is annotated with @Component it will be singleton. ie only one instance for the lifetime of the JVM. If you want Spring managed resources to have the same per-request life-cycle that comes with normal Jersey resources then you should add the Spring @Scope(scopeName = WebApplicationContext.SCOPE_REQUEST) annotation in addition to the @Component annotation. By adding it your resource life-cycle will now be per-request.