简体   繁体   English

何时使用Jersey的@Singleton注释?

[英]When to use @Singleton annotation of Jersey?

I am developing a RESTful Web Service and while reading the Jersey documentation I came across an annotation @Singleton 我正在开发一个RESTful Web服务,在阅读Jersey 文档时,我遇到了一个注释@Singleton

In my web service I am mostly returning data based on the unique keys provided as parameter. 在我的Web服务中,我主要根据作为参数提供的唯一键返回数据。 An analogy would be return all the information of a Student when the Student_Id is passed. 当Student_Id通过时,类比将返回学生的所有信息。

So my question is when @Singleton would be suited in such kind of Web Services? 所以我的问题是@Singleton何时适合这种Web服务?

As per documentation for @RequestScoped 根据@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? 那么在那种情况下我们不应该费心去使用@Singleton吗?

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. 我确实看过这篇文章,但我的问题没有得到解答。

By default Jersey creates a new instance of the resource class for every request. 默认情况下,Jersey为每个请求创建资源类的新实例。 So if you don't annotate the Jersey resource class, it implicitly uses @RequestScoped scope. 因此,如果您不注释Jersey资源类,它会隐式使用@RequestScoped范围。 It is stated in Jersey documentation : Jersey文件中说明

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. 大多数情况下,您使用此默认设置,因此您不使用@Singleton范围。 You can also create a singleton Jersey resource class by using @Singleton annotation. 您还可以使用@Singleton注释创建单例Jersey资源类。 Then you need to register the singleton class in the MyApplication class, eg, 然后你需要在MyApplication类中注册singleton类,例如,

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

public class MyApplication extends ResourceConfig {

    /*Register JAX-RS application components.*/
    public MyApplication () {
        register(JerseySingletonClass.class);
    }
}

Came along this question, because for the first time I had a use case for not using @Singleton annotation. 提出这个问题,因为我第一次有一个不使用 @Singleton注释的用例。

Singleton is a design pattern, you should use it if: Singleton是一种设计模式,如果符合以下条件,您应该使用它:

  • The object you are "singletonizing" keeps a state that must be shared and kept unique (example: a global counter) 您正在“单一化”的对象保持一个必须共享并保持唯一的状态(例如:全局计数器)
  • Generally, I design REST API without keeping a state, everything is handled in the method (full closure): so generally all my resources are singletons (use case: better performance) 通常,我设计REST API而不保持状态,一切都在方法中处理(完全关闭):所以我的所有资源通常都是单例(用例:更好的性能)

That said, today I found this use case for not using Singleton: 也就是说,今天我发现这个用例不使用Singleton:

@Path("/someendpoint/{pathparam}/somethingelse/")
//@Singleton
public class MyResource {
    @PathParam("pathparam")
    private String pathparam;
}

Using this, I'm bounding the path param to my instance, so it must be RequestScoped. 使用这个,我将路径参数绑定到我的实例,因此它必须是RequestScoped。 Generally, I'd have put @PathParam annotation in every method, so @Singleton would have been right on the class. 一般来说,我已经在每个方法中都放了@PathParam注释,所以@Singleton在这个类中是正确的。

I'm not sure about the performances however, creating and destroying an object isn't a free operation 然而,我不确定性能,创建和销毁对象不是免费操作

In most cases default scope @RequestScoped should be sufficient for your needs. 在大多数情况下,默认范围@RequestScoped应该足以满足您的需求。

@Singleton may hold state. @Singleton可能会持有州。 I had the problem when my endpoint was annotated as @Singleton so it reused the same EntityManager during concurrent calls. 当我的端点被注释为@Singleton时,我遇到了问题,所以它在并发调用期间重用了相同的EntityManager After removing @Singleton , during concurrent calls, different EntityManager object instances are used. 删除@Singleton ,在并发调用期间,将使用不同的EntityManager对象实例。 If endpoint calls are subsequent, it may be that previous/old EntityManager will be used. 如果端点调用是后续的,则可能使用先前/旧的EntityManager - Jersey, Guice and Hibernate - EntityManager thread safety - Jersey,Guice和Hibernate - EntityManager线程安全

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 实际上在Jersey 2手册中指定了在服务于Server-Sent事件时使用SseBroadcaster的用例, 在此提供的示例中对此进行了介绍

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. BroadcasterResource资源类使用@Singleton注释进行注释,该注释告诉Jersey运行时只应使用资源类的单个实例来为/广播路径提供所有传入请求。 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. 想要侦听SSE事件的客户端首先向BroadcasterResource发送GET请求,该请求由listenToBroadcast()资源方法处理。

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! 使用@Singleton ,应用程序将只包含一个SseBroadcaster用于所有传入请求,一个这样的广播器足以为多个客户端提供服务,因此它只需要实例化一次!

JAX-RS SSE API defines SseBroadcaster which allows to broadcast individual events to multiple clients. JAX-RS SSE API定义了SseBroadcaster,它允许向多个客户端广播单个事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM