When to use @Singleton annotation of Jersey?

2019-01-11 22:28发布

I am developing a RESTful Web Service and while reading the Jersey documentation I came across an annotation @Singleton

In my web service I am mostly returning data based on the unique keys provided as parameter. An analogy would be return all the information of a Student when the Student_Id is passed.

So my question is when @Singleton would be suited in such kind of Web Services?

As per documentation for @RequestScoped

If the resource is used more than one time in the request processing, always the same instance will be used.

Then in that case we should not bother to use @Singleton right?

Also what could be the use cases where we have to make a new instance for every request?

I did have a look at this post but my question was not answered.

标签: java rest jersey
3条回答
何必那么认真
2楼-- · 2019-01-11 22:39

There is actually a use case specified in the Jersey 2 manual for using the SseBroadcaster when serving Server-Sent events, it is covered in this provided example

The BroadcasterResource resource class is annotated with @Singleton annotation which tells Jersey runtime that only a single instance of the resource class should be used to serve all the incoming requests to /broadcast path. This is needed as we want to keep an application-wide single reference to the private broadcaster field so that we can use the same instance for all requests. Clients that want to listen to SSE events first send a GET request to the BroadcasterResource, that is handled by the listenToBroadcast() resource method.

Using the @Singleton, The application will only contain one SseBroadcaster for all incoming requests, one such broadcaster is enough to serve multiple clients, so it only needs to be instantiated once!

JAX-RS SSE API defines SseBroadcaster which allows to broadcast individual events to multiple clients.

查看更多
啃猪蹄的小仙女
3楼-- · 2019-01-11 22:50

In most cases default scope @RequestScoped should be sufficient for your needs.

@Singleton may hold state. I had the problem when my endpoint was annotated as @Singleton so it reused the same EntityManager during concurrent calls. After removing @Singleton, during concurrent calls, different EntityManager object instances are used. If endpoint calls are subsequent, it may be that previous/old EntityManager will be used. - Jersey, Guice and Hibernate - EntityManager thread safety

查看更多
The star\"
4楼-- · 2019-01-11 23:02

By default Jersey creates a new instance of the resource class for every request. So if you don't annotate the Jersey resource class, it implicitly uses @RequestScoped scope. It is stated in Jersey documentation:

Default lifecycle (applied when no annotation is present). In this scope the resource instance is created for each new request and used for processing of this request. If the resource is used more than one time in the request processing, always the same instance will be used. This can happen when a resource is a sub resource is returned more times during the matching. In this situation only on instance will server the requests.

Most cases you use this default setting so you don't use @Singleton scope. You can also create a singleton Jersey resource class by using @Singleton annotation. Then you need to register the singleton class in the MyApplication class, e.g.,

@Path("/resource")
@Singleton
public class JerseySingletonClass {
    //methods ...
}

public class MyApplication extends ResourceConfig {

    /*Register JAX-RS application components.*/
    public MyApplication () {
        register(JerseySingletonClass.class);
    }
}
查看更多
登录 后发表回答