Jsf 如何选择正确的bean范围?

Jsf 如何选择正确的bean范围?,jsf,jsf-2,scope,managed-bean,Jsf,Jsf 2,Scope,Managed Bean,我注意到有不同的bean作用域,如: @RequestScoped @ViewScoped @FlowScoped @SessionScoped @ApplicationScoped 每种方法的目的是什么?如何为我的bean选择合适的范围?简介 它表示bean的作用域(生命周期)。如果您熟悉基本servlet web应用程序的“幕后”工作,则更容易理解: @Request/View/Flow/Session/ApplicationScoped bean的寿命与单个HTTP请求响应周期一样长(

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

@RequestScoped
@ViewScoped
@FlowScoped
@SessionScoped
@ApplicationScoped
每种方法的目的是什么?如何为我的bean选择合适的范围?

简介 它表示bean的作用域(生命周期)。如果您熟悉基本servlet web应用程序的“幕后”工作,则更容易理解:


@Request/View/Flow/Session/ApplicationScoped
bean的寿命与单个HTTP请求响应周期一样长(请注意,Ajax请求也算作单个HTTP请求)。只要您通过回发与相同的JSF视图交互,bean就会存在,回发调用返回
null
/
void
的操作方法,而不进行任何导航/重定向。只要您在流配置文件中注册的指定视图集合中导航,bean就会一直存在。bean的寿命与已建立的HTTP会话一样长。只要web应用程序运行,bean就会一直存在。请注意,CDI
@Model
基本上是名为@RequestScoped的
@for,因此同样的规则也适用

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

@ApplicationScoped
bean用于会话/视图/请求范围的数据将使其在所有用户之间共享,因此其他任何人都可以看到彼此的数据,这是完全错误的。将
@SessionScoped
bean用于查看/请求范围的数据将使其在单个浏览器会话中在所有选项卡/窗口之间共享,因此最终用户在切换选项卡后与每个视图交互时可能会遇到不协调的情况,这不利于用户体验。滥用
@RequestScoped
bean查看范围数据会使查看范围数据在每次(ajax)回发时重新初始化为默认值,可能会导致非工作表单()。对请求、会话或应用程序范围的数据滥用
@ViewScoped
bean,对应用程序范围的数据滥用
@SessionScoped
bean不会影响客户端,但它会不必要地占用服务器内存,效率低下

请注意,不应根据性能影响来选择范围,除非您的内存占用率很低,并且希望完全无状态;您需要专门使用
@RequestScoped
bean并修改请求参数来维护客户端的状态。还请注意,当您有一个包含不同范围数据的单一JSF页面时,将它们放在与数据范围相匹配的范围内的单独的支持bean中是完全有效的。对于JSF管理的bean,bean可以通过
@ManagedProperty
相互访问;对于CDI管理的bean,bean可以通过
@Inject
相互访问

另见:

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

JSF
@NoneScoped
和CDI基本上与bean上的单个EL评估一样长。设想一个登录表单,其中两个输入字段引用一个bean属性,一个命令按钮引用一个bean操作,因此总共有三个EL表达式,那么实际上将创建三个实例。一个设置了用户名,一个设置了密码,还有一个调用了操作。您通常只想在bean上使用这个作用域,它应该和注入它的bean一样长。因此,如果在
@SessionScoped
中注入
@NoneScoped
@Dependent
,那么它将与
@SessionScoped
bean一样长

另见:

闪光镜 最后,JSF还支持flash作用域。它由一个与会话作用域中的数据项关联的短期cookie支持。在重定向之前,将在HTTP响应上设置一个cookie,其值与会话范围中的数据项唯一关联。重定向后,将检查flash scope cookie是否存在,并且与cookie关联的数据条目将从会话作用域中删除,并放入重定向请求的请求作用域中。最后,cookie将从HTTP响应中删除。通过这种方式,重定向请求可以访问在初始请求中准备的请求范围数据

这实际上不是托管bean作用域,也就是说,没有
@FlashScoped
这样的东西。flash作用域仅在托管bean和EL中的
#{flash}
中作为映射提供

另见:

自JSF2.3以来,包
javax.faces.bean
包中定义的所有bean作用域都已被弃用,以将作用域与CDI对齐。此外,它们仅在bean使用
@ManagedBean
注释时适用。如果您使用的是低于2.3的JSF版本,请参阅最后的遗留答案


在JSF2.3中,以下是c