Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jsf 数据库表示的应用程序范围Bean还是单例?_Jsf_Jakarta Ee_Singleton_Ejb - Fatal编程技术网

Jsf 数据库表示的应用程序范围Bean还是单例?

Jsf 数据库表示的应用程序范围Bean还是单例?,jsf,jakarta-ee,singleton,ejb,Jsf,Jakarta Ee,Singleton,Ejb,我将信息存储在一个数据库中(实际上是一个内容存储库,但这不重要),它应该呈现给所有用户。目前我有一个单例Bean,它获取这些信息并将其存储在一个变量中。每次更新数据库时都会调用此获取操作,以便表示数据库内容的变量始终是最新的。jsf托管bean也使用这个变量来显示信息。我希望通过这种方法避免的是,必须为每个只读请求打开一个新的数据库连接。这种方法有意义吗?还是应该改用应用程序范围的托管bean?然后,我必须从EJB中调用托管bean的update方法。这样做有什么不对吗?如果您希望在JSF中跨给

我将信息存储在一个数据库中(实际上是一个内容存储库,但这不重要),它应该呈现给所有用户。目前我有一个单例Bean,它获取这些信息并将其存储在一个变量中。每次更新数据库时都会调用此获取操作,以便表示数据库内容的变量始终是最新的。jsf托管bean也使用这个变量来显示信息。我希望通过这种方法避免的是,必须为每个只读请求打开一个新的数据库连接。这种方法有意义吗?还是应该改用应用程序范围的托管bean?然后,我必须从EJB中调用托管bean的update方法。这样做有什么不对吗?

如果您希望在JSF中跨给定web应用程序的所有会话持久化信息,那么最好使用应用程序范围,而不是使用静态单例

以下是一些原因:

  • 静态字段基于特定VM中加载的类。如果要对应用程序进行负载平衡或群集,则其他应用程序服务器节点不可能访问存储在其他VM服务器上的信息

  • ApplicationScoped bean可以序列化,这意味着某些web和应用程序容器能够在服务器重新启动时将这些作用域bean持久化到磁盘。但是,这取决于给定服务器的功能

  • 某些应用服务器具有良好的集群支持、粘性会话和全局集群应用范围。如果当前会话服务器意外停机,这将允许会话成功路由到另一台服务器。此外,应用程序范围的bean将在整个应用程序中的任何地方都是公共的和可访问的,而不管哪个节点正在为给定的请求提供服务。同样,这在很大程度上取决于应用程序容器特性和配置

  • 静态字段不仅可供给定应用程序VM上的每个请求访问,还可供给定VM上运行的每个应用程序上的每个请求使用。如果应用服务器或web容器正在运行多个web应用程序,并且它们都使用相同的类,那么它们可能会无意中共享信息或相互冲突。这不是一个好的设计选择

  • 有关更多信息,请参见下文:


    这个问题的表达方式暗示您正在使用普通的JDBC,而不是JPA+JTA+connectionpool。这是真的吗?好吧,看来内容存储库毕竟还是有意思的。我使用jcr api作为资源适配器,使用jackrabbit作为实现,用于接收信息谢谢您的输入。在我的情况下,我不想在所有会话中持久化数据。我只想在所有请求中显示相同的数据。因此,我正在寻找最好的方式向每个用户显示数据库内容,而无需为每个用户打开直接的数据库连接…@user1644061但原理相同。。。您将为所有请求持久化一个应用程序范围的bean,而这个bean恰好有一个对数据源连接的引用。不过,仅仅拥有一个连接本身是不安全的,如果发生了什么事情,并且当前连接最终关闭,那么最好是引用一个连接工厂,该工厂将为您创建一个新连接。好的,非常感谢,我将使用一个应用程序范围的bean。根据您的回答,我想从EJB中调用bean没有什么错吧?而且:由于应用程序范围的bean只实例化一次,所以在其中包含方法是否有问题?例如,一个允许用户在saveas对话框中下载文件的方法?@user1644061我认为ApplicationScoped bean在被注入另一个bean的新创建的托管属性时被实例化,并且只有当它还不存在时才被实例化。除非您使用单独的DI容器,如CDI或Spring,否则它还需要可序列化,因为它本质上是在内存或临时磁盘空间中的ApplicationsServletContext中序列化applicationscoped bean。只要服务器在运行,或者应用程序未部署,或者从ServletContext手动删除或销毁,它就会一直存在。