【问题标题】:Singleton in a ServletServlet 中的单例
【发布时间】:2013-11-20 08:11:41
【问题描述】:

我可以在 servlet 中使用单例在不同会话之间共享信息吗?

我知道任何时候只有 1 个实例 Servlet 正在运行。为每个传入请求调用服务方法。但是如何创建另一个在 servlets Init() 方法中调用其 getInstance() 的 Singleton 类(例如:ShareSingleton)。这个 ShareSingleton 可以携带需要在会话/请求之间共享的数据。

在 servlet 中使用这种方法是否有风险?

【问题讨论】:

标签: java servlets singleton


【解决方案1】:

首先..查看此单例的最佳方法:http://javarevisited.blogspot.com/2012/07/why-enum-singleton-are-better-in-java.html

第二:记住单例只适用于 JVM。所以..如果您运行多个 JVM,不要期​​望每个单例具有相同的状态。

第三:为了安全起见,我将从 servlet 上下文的侦听器中实例化单例。

http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContextListener.html

在你的 web.xml 中定义一个类并在那里实例化它。您的单例将在您的 web 应用启动时创建,而不是在 n 人同时点击您的 servlet 的服务方法时创建。

【讨论】:

  • 谢谢。 1. 我正在使用枚举单例。 2. 这正是我不想使用 ApplicationContext 的原因。我还需要为每个 JVM 存储信息(对于集群应用程序)
  • 我可以补充。在 servlet 的 init 中实例化 Singleton 是可以的……在这种情况下。它已经在 web.xml 中定义,并在您的服务器启动时被实例化。然而……这不是最好的。就像我说的。如果您有一个负载均衡器正在过滤 10 个 JVM 之间的流量。谁知道 JVM n 上的单例是什么..
  • 所以你使用的是 Spring?单例是否保持状态?
  • 对不起。我刚刚再次阅读了您的回复...我回答了我自己的问题。你在这个单例中持有什么信息,为什么不能通过配置实现?
  • 我正在使用它来保存一些 ManagedServer 统计信息,例如每个 JVM/ManagedServer 提供的负载/noofrequests。
【解决方案2】:

是的,你可以。请注意,servlet 容器可能使用 Servlet 对象的多个实例,因此您必须确保在所有这些实例之间共享一个对象。

例如,你可以这样做:

private static final Cache<String,String> = //cache

然后使用缓存中的值(如果可用),否则使用新计算的值更新缓存。请注意,共享的对象必须是线程安全的。

【讨论】:

  • 不太清楚你在说什么? “请注意,servlet 容器可能会使用 Servlet 对象的多个实例”? Servlet 只创建一次来处理请求。你是说 JVM 吗?
  • 恩诺是对的。您可以在 web.xml 中使用不同的名称两次声明同一个 servlet 类,某些容器可能会创建 servlet 实例池。
  • 有趣。你每天都会学到一些东西。你能详细说明一下容器吗?
  • 看起来规范指定它不会,除非实现了 SingleThreadModel(已弃用)。不知道为什么我认为它会经常这样做......@Slihp
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-03
  • 2012-01-06
  • 2012-10-20
  • 2014-04-07
  • 1970-01-01
  • 2012-08-02
  • 2013-06-02
相关资源
最近更新 更多