27

我正在开发一个 RESTful Web 服务,在阅读 Jersey文档时我遇到了一个注释@Singleton

在我的网络服务中,我主要根据作为参数提供的唯一键返回数据。当 Student_Id 被传递时,类比将返回一个学生的所有信息。

所以我的问题是什么时候@Singleton适合这种网络服务?

根据文档@RequestScoped

如果资源在请求处理中被多次使用,则始终使用同一个实例。

那么在那种情况下我们不应该费心使用@Singleton吧?

另外,我们必须为每个请求创建一个新实例的用例可能是什么?

我确实看过这篇文章,但我的问题没有得到回答。

4

4 回答 4

27

默认情况下,Jersey 会为每个请求创建一个资源类的新实例。因此,如果您不注释 Jersey 资源类,它会隐式使用@RequestScoped范围。泽西岛文档中有说明:

默认生命周期(在不存在注释时应用)。在此范围内,为每个新请求创建资源实例并用于处理此请求。如果资源在请求处理中被多次使用,则始终使用同一个实例。当资源是子资源在匹配期间返回更多次时,可能会发生这种情况。在这种情况下,只有在实例上才会处理请求。

大多数情况下,您使用此默认设置,因此您不使用@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);
    }
}
于 2013-12-10T21:43:23.277 回答
2

Came along this question, because for the first time I had a use case for not using @Singleton annotation.

Singleton is a design pattern, you should use it if:

  • 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)

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 must be RequestScoped. Generally, I'd have put @PathParam annotation in every method, so @Singleton would have been right on the class.

I'm not sure about the performances however, creating and destroying an object isn't a free operation

于 2019-06-12T06:40:38.703 回答
1

在大多数情况下,默认范围@RequestScoped应该足以满足您的需求。

@Singleton可以保持状态。当我的端点被注释时,我遇到了问题,因此它在并发调用期间@Singleton重用了相同的端点。EntityManager移除 后@Singleton,在并发调用期间,EntityManager会使用不同的对象实例。如果端点调用是后续的,则可能会使用先前/旧的EntityManager。- Jersey、Guice 和 Hibernate - EntityManager 线程安全

于 2018-03-21T13:40:42.390 回答
0

实际上,Jersey 2 手册中指定了一个用例,用于在服务服务器发送事件时使用SseBroadcaster ,它包含在这个提供的示例中

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!

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

于 2018-06-17T09:52:43.550 回答