Java 何时使用 Jersey 的 @Singleton 注释?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18914130/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When to use @Singleton annotation of Jersey?
提问by Sam
I am developing a RESTful Web Service and while reading the Jersey documentationI 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. An analogy would be return all the information of a Student when the Student_Id is passed.
在我的 Web 服务中,我主要根据作为参数提供的唯一键返回数据。当Student_Id被传递时,类比将返回Student的所有信息。
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 thispost but my question was not answered.
我确实看过这篇文章,但我的问题没有得到解答。
采纳答案by tonga
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:
默认情况下,Jersey 为每个请求创建一个资源类的新实例。因此,如果您不注释 Jersey 资源类,它会隐式使用@RequestScoped
范围。在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. 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.,
大多数情况下,您使用此默认设置,因此不使用@Singleton
范围。您还可以使用@Singleton
注释创建一个单例 Jersey 资源类。然后你需要在类中注册单例MyApplication
类,例如,
@Path("/resource")
@Singleton
public class JerseySingletonClass {
//methods ...
}
public class MyApplication extends ResourceConfig {
/*Register JAX-RS application components.*/
public MyApplication () {
register(JerseySingletonClass.class);
}
}
回答by Justas
In most cases default scope @RequestScoped
should be sufficient for your needs.
在大多数情况下,默认范围@RequestScoped
应该足以满足您的需求。
@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
@Singleton
可以保持状态。当我的端点被注释时我遇到了问题,@Singleton
因此它EntityManager
在并发调用期间重用了相同的端点。移除后@Singleton
,在并发调用期间,EntityManager
会使用不同的对象实例。如果端点调用是后续的,则可能会使用以前的/旧的EntityManager
。- Jersey、Guice 和 Hibernate - EntityManager 线程安全
回答by svarog
There is actually a use case specified in the Jersey 2 manual for using the SseBroadcasterwhen 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. 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.
BroadcasterResource 资源类使用 @Singleton 批注进行批注,该批注告诉 Jersey 运行时只应使用资源类的单个实例来为所有传入 /broadcast 路径的请求提供服务。这是必需的,因为我们希望保留对私有广播者字段的应用程序范围的单一引用,以便我们可以对所有请求使用相同的实例。想要监听 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,它允许向多个客户端广播单个事件。
回答by besil
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:
单例是一种设计模式,你应该在以下情况下使用它:
- The object you are "singletonizing" keeps a state that must be sharedand 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 allmy resources are singletons (use case: better performance)
- 您正在“单一化”的对象保持必须共享并保持唯一的状态(例如:全局计数器)
- 一般来说,我设计的 REST API 没有保持状态,一切都在方法中处理(完全关闭):所以一般我所有的资源都是单例(用例:更好的性能)
That said, today I found this use case for not using 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 mustbe RequestScoped. Generally, I'd have put @PathParam annotation in every method, so @Singleton would have been right on the class.
使用这个,我将路径参数绑定到我的实例,所以它必须是 RequestScoped。通常,我会在每个方法中添加 @PathParam 注释,所以 @Singleton 应该是正确的。
I'm not sure about the performances however, creating and destroying an object isn't a free operation
我不确定性能但是,创建和销毁对象不是免费操作