何时使用泽西岛的@Singleton注释?

2022-09-01 16:01:50

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

在我的Web服务中,我主要根据作为参数提供的唯一键返回数据。打个比方,当Student_Id通过时,将返回学生的所有信息。

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

根据文档@RequestScoped

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

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

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

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


答案 1

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

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

大多数情况下,您使用此默认设置,因此不使用范围。您还可以使用批注创建单例 Jersey 资源类。然后,您需要在该类中注册单例类,例如,@Singleton@SingletonMyApplication

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

public class MyApplication extends ResourceConfig {

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

答案 2

出现了这个问题,因为我第一次有了一个不使用@Singleton注释的用例。

单例是一种设计模式,在以下情况下应使用它:

  • 要“单一化”的对象保留必须共享并保持唯一的状态(例如:全局计数器)
  • 通常,我在设计REST API时不保持状态,所有内容都在方法中处理(完全闭包):因此通常我的所有资源都是单例(用例:更好的性能)

也就是说,今天我发现了这个不使用Singleton的用例:

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

使用这个,我将路径参数绑定到我的实例,因此它必须是RequestScoped。一般来说,我会在每个方法中都放置@PathParam注释,所以@Singleton在类上是正确的。

我不确定性能,但是,创建和销毁对象不是免费操作