关于jsf:如何选择合适的bean范围?

How to choose the right bean scope?

我注意到有不同的bean作用域,比如:

1
2
3
4
5
@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped

每种方法的目的是什么?如何为我的bean选择合适的范围?


介绍

它表示bean的作用域(生存期)。如果您熟悉基本servlet Web应用程序的"幕后"工作,那么这就更容易理解:servlet是如何工作的?实例化、会话、共享变量和多线程。好的。@Request/View/Flow/Session/ApplicationScoped

@RequestScopedbean的寿命与单个HTTP请求响应周期一样长(注意,Ajax请求也算作单个HTTP请求)。只要通过回发与同一个JSF视图交互,@ViewScopedbean就可以生存,它调用返回null/void的操作方法,而不需要任何导航/重定向。只要您在流配置文件中注册的指定视图集合中导航,@FlowScopedbean就会一直存在。@SessionScopedbean与已建立的HTTP会话一样长。只要Web应用程序运行,@ApplicationScopedbean就可以生存。请注意,CDI @Model基本上是@Named @RequestScoped的一个刻板印象,所以同样的规则也适用。好的。

选择哪个范围完全取决于bean保存和表示的数据(状态)。对于简单和非Ajax表单/演示,使用@RequestScoped。将@ViewScoped用于支持丰富Ajax的动态视图(基于Ajax的验证、呈现、对话框等)。使用@FlowScoped作为"向导"("问卷")模式,收集分布在多个页面上的输入数据。将@SessionScoped用于特定于客户机的数据,例如登录的用户和用户首选项(语言等)。对应用程序范围的数据/常量使用@ApplicationScoped,例如对每个人都相同的下拉列表,或者没有任何实例变量且只有方法的托管bean。好的。

对会话/视图/请求范围的数据使用@ApplicationScopedbe an将使其在所有用户之间共享,这样任何其他人都可以看到彼此的数据,这显然是错误的。对视图/请求范围的数据使用@SessionScopedbean将使其在单个浏览器会话中在所有选项卡/窗口之间共享,因此最终用户在切换选项卡后与每个视图交互时可能会遇到不便,这对用户体验不利。对视图范围的数据使用@RequestScopedbean会使视图范围的数据在每次回发(ajax)时都重新初始化为默认值,从而导致可能的非工作表单(请参见此处的第4点和第5点)。对请求、会话或应用程序范围的数据滥用@ViewScopedbean,对应用程序范围的数据滥用@SessionScopedbean不会影响客户机,但它不必要地占用服务器内存,效率低下。好的。

请注意,不应根据性能影响来选择作用域,除非您的内存占用量确实很低,并且希望完全无状态;您需要专门使用@RequestScopedbean,并处理请求参数以维护客户机的状态。还要注意,当您有一个具有不同作用域数据的JSF页面时,将它们放在与数据作用域匹配的作用域中的单独的支持bean中是完全有效的。对于JSF管理的bean,bean可以通过@ManagedProperty进行访问;对于CDI管理的bean,bean可以通过@Inject进行访问。好的。参见:

  • 托管bean中视图和请求范围的区别
  • 使用JSF面流而不是普通导航系统的优点
  • JSF2中的通信-托管bean范围

@CustomScoped/NoneScoped/Dependent

在您的问题中没有提到,但是(遗留)JSF也支持@CustomScoped@NoneScoped,这在现实世界中很少使用。@CustomScoped必须在更广泛的范围内引用自定义Map实现,该实现覆盖了Map#put()和/或Map#get()以对bean的创建和/或销毁进行更细粒度的控制。好的。

jsf @NoneScoped和cdi @Dependent基本上只要对bean进行一次EL评估就可以使用。假设一个登录表单有两个输入字段引用一个bean属性,一个命令按钮引用一个bean操作,因此总共有三个el表达式,那么实际上将创建三个实例。一个设置了用户名,一个设置了密码,另一个调用操作。您通常只想在bean上使用这个作用域,bean应该和注入它的bean一样长。因此,如果一个@NoneScoped@Dependent被注入@SessionScoped中,那么它的寿命将与@SessionScoped豆一样长。好的。参见:

  • 在时间间隔后过期特定的托管bean实例
  • 什么是无范围bean以及何时使用它?
  • JSF 2应用程序中的默认托管bean范围是什么?

闪光范围

最后,JSF还支持Flash范围。它由一个与会话范围中的数据条目相关联的短活动cookie支持。在重定向之前,将在HTTP响应上设置一个cookie,该cookie的值与会话范围中的数据条目唯一关联。重定向后,将检查闪存作用域cookie的存在,并将与cookie关联的数据条目从会话作用域中删除,并将其放入重定向请求的请求作用域中。最后,cookie将从HTTP响应中删除。这样重定向的请求就可以访问在初始请求中准备的请求范围数据。好的。

这实际上不能作为一个托管bean范围来使用,也就是说,没有像@FlashScoped这样的东西。flash scope只能通过管理bean中的ExternalContext#getFlash()和el中的#{flash}作为映射提供。好的。参见:

  • 如何在重定向页面中显示人脸消息
  • 在@viewscoped bean之间传递一个对象,而不使用get-params
  • cdi缺少@viewscoped和@flashscoped

好啊。


As of JSF 2.x there are 4 Bean Scopes:

  • @SessionScoped
  • @RequestScoped
  • @ApplicationScoped
  • @ViewScoped

Session Scope: The session scope persists from the time that a session is established until session termination. A session terminates
if the web application invokes the invalidate method on the
HttpSession object, or if it times out.

RequestScope: The request scope is short-lived. It starts when an HTTP request is submitted and ends after the response is sent back
to the client. If you place a managed bean into request scope, a new
instance is created with each request. It is worth considering request
scope if you are concerned about the cost of session scope storage.

ApplicationScope: The application scope persists for the entire duration of the web application. That scope is shared among all
requests and all sessions. You place managed beans into the
application scope if a single bean should be shared among all
instances of a web application. The bean is constructed when it is
first requested by any user of the application, and it stays alive
until the web application is removed from the application server.

ViewScope: View scope was added in JSF 2.0. A bean in view scope persists while the same JSF page is redisplayed. (The JSF
specification uses the term view for a JSF page.) As soon as the user
navigates to a different page, the bean goes out of scope.

Choose the scope you based on your requirement.

来源:核心Java服务器面向David Geary和Cay Horstmann的第三版[第51页-第54页]enter image description here