我将信息存储在数据库中(实际上是一个内容存储库,但这无关紧要),这些信息应该呈现给所有用户。目前我有一个 Singleton Bean,它获取这些信息并将其存储在一个变量中。每次数据库发生更新时都会调用此提取操作,以便表示数据库内容的变量始终是最新的。jsf 托管 bean 也使用此变量来显示信息。我想用这种方法避免的是必须为每个只读请求打开一个新的数据库连接。这种方法有意义还是我应该使用应用程序范围的托管 bean?然后我必须从 EJB 中调用托管 bean 的更新方法。这样做有什么问题吗?
1 回答
如果您想在 JSF 中跨给定 Web 应用程序的所有会话中保留信息,那么最好使用 Application Scoped 而不是使用静态单例。
以下是几个原因:
静态字段基于特定 VM 中加载的类。如果您的应用程序要进行负载平衡或集群,则其他应用程序服务器节点不可能访问存储在其他服务器 VM 上的信息。
ApplicationScoped bean 可以是可序列化的,这意味着某些 Web 和应用程序容器能够在服务器重新启动时将这些作用域 bean 持久化到磁盘。但是,这取决于给定服务器的功能。
某些应用程序服务器具有良好的集群支持以及粘性会话和全局集群范围的应用程序范围。如果当前会话服务器意外关闭,这将允许会话成功路由到另一台服务器。此外,ApplicationScoped bean 将是公共的,并且可以在整个应用程序中随处访问,无论哪个节点正在为给定请求提供服务。同样,这高度依赖于应用程序容器的特性和配置。
静态字段不仅对给定应用程序的 VM 上的每个请求都可访问,而且对给定 VM 上运行的每个应用程序上的每个请求都可用。如果应用程序服务器或 Web 容器正在运行多个 Web 应用程序并且它们都使用相同的类,那么它们可能会无意中共享信息或相互冲突。不是一个好的设计选择。
有关更多信息,请参见下文:
https://blogs.oracle.com/groundside/entry/application_scope_v_s_static