我最近读了Neil Griffin的文章《区分不同种类的JSF managed - bean》,这篇文章让我开始思考在我自己的应用程序中不同bean之间的区别。快速总结要点:
模型管理bean:这种类型的管理bean参与MVC设计模式的"模型"关注点。当你看到这个词"模型"——考虑数据。JSF模型bean应该是下面的POJO使用getter/setter封装的JavaBean设计模式属性。
Backing Managed-Bean:这种类型的Managed-Bean参与"视图"关注MVC设计模式。a的目的backingbean是支持UI逻辑的,并且与UI逻辑具有1::1的关系JSF视图,或者Facelet组合中的JSF表单。尽管它通常具有javabean风格的属性getter/setter,这些是View的属性,而不是底层应用程序数据模型。JSF支持bean也可能具有JSF
Controller Managed-Bean:这种类型的管理bean参与MVC设计模式的"控制器"关注点。a的目的控制器bean执行某种业务逻辑并返回一个导航输出到JSF导航处理程序。JSF controller-beans通常有JSF动作方法(而不是actionListener方法)。
支持Managed-Bean:这种类型的bean"支持"一个或多个视图在MVC设计模式的"视图"关注点中。典型用例是提供一个数组列表JSF h:selectOneMenu下拉菜单在多个JSF视图中出现的列表。中的数据下拉列表是特定于用户的,那么bean将被保留
Utility Managed-Bean:这种类型的bean提供了某种类型的"实用程序"函数到一个或多个JSF视图。这是一个很好的例子可能是一个可以在多个web中重用的FileUpload bean应用。
这对我来说是有意义的,在过去的几个小时里,我一直在重构我的代码,并提出了以下关于用户登录的内容:
AuthenticationController
是Controller Managed-Bean的一个例子。它是请求范围的,具有两个getter和setter,用于设置用户名和密码,以及两个导航方法,authenticate
和logout
,在成功登录时导航用户到他们的私人区域,或在注销时返回主页面。
UserBean
是一个支持管理bean的例子。它是会话范围的,并具有User
类的实例(当您未进行身份验证时将为null),具有getter和setter,仅此而已。
AuthenticationController
将此用户作为托管属性(@ManagedProperty(value = "#{userController.user} private User user;
)。身份验证成功后,AuthenticationController
将托管属性设置为实际用户实例,并使用登录时使用的相应用户名。
如果User
类具有组名列表,则任何新的bean都能够将用户作为托管属性抓取并提取所需的数据,例如组成员资格。
这种方法是关于关注点分离的正确方法吗?
这是一个非常主观的问题。我个人不同意那篇文章,并且发现它给初学者的建议真的很糟糕。
Model Managed-Bean:这种类型的Managed-Bean参与MVC设计模式的"模型"关注点。当你看到"模型"这个词时——想想数据。JSF模型bean应该是遵循JavaBean设计模式的POJO,使用getter/setter封装属性。
我绝对不会创建或称其为托管bean。让它成为@ManagedBean
的一个属性。例如DTO或JPA @Entity
。
Backing Managed-Bean:这种类型的Managed-Bean参与MVC设计模式的"View"关注点。支持bean的目的是支持UI逻辑,并与JSF视图或Facelet组合中的JSF表单具有1::1的关系。尽管它通常具有带有关联getter/setter的javabean风格属性,但这些都是视图的属性——而不是底层应用程序数据模型的属性。JSF支持bean也可以有JSF actionListener和valueChangeListener方法。
通过这种方式,您可以继续复制和映射托管bean中实体的属性。这对我来说毫无意义。如前所述,只需将实体作为托管bean的属性,并让输入字段直接引用它,如#{authenticator.user.name}
而不是#{authenticator.username}
。
Controller Managed-Bean:这种类型的Managed-Bean参与了MVC设计模式的"Controller"关注点。控制器bean的目的是执行某种业务逻辑,并将导航结果返回给JSF导航处理程序。JSF控制器bean通常具有JSF操作方法(而不是actionListener方法)。
这里非常详细地描述了@RequestScoped
/@ViewScoped
@ManagedBean
类。事件侦听器方法是否被允许取决于它们是否特定于绑定到bean的视图和/或它们的工作依赖于bean的状态。如果它们是,那么它们就属于豆子。如果没有,那么它们应该是任何FacesListener
接口的独立实现,但绝对不是托管bean。
支持Managed-Bean:这种类型的bean在MVC设计模式的"视图"关注点中"支持"一个或多个视图。典型的用例是向出现在多个JSF视图中的JSF h:selectOneMenu下拉列表提供ArrayList。如果下拉列表中的数据是特定于用户的,那么bean将保留在会话范围内。
好。对于应用程序范围的数据,如下拉列表,只需使用@ApplicationScoped
bean;对于会话范围的数据,如登录用户及其首选项,只需使用@SessionScoped
bean。
Utility Managed-Bean:这种类型的bean为一个或多个JSF视图提供了某种类型的"实用程序"功能。可以在多个web应用程序中重用的FileUpload bean就是一个很好的例子。
这对我来说没有意义。支持bean通常绑定到单个视图。这听起来太像ActionListener
的实现了,它将由<f:actionListener>
在命令组件中使用,由您选择。绝对不是一个受管理的bean。
有关正确方法的启动示例,请参见:
- 我们的JSF wiki页面中的Hello World示例
- "Bookstore CRUD"的示例
- "Master-detail"在这个回答中的例子 JSF服务层
- JSF 2中的通信