区分不同类型的 JSF 托管 Bean

2022-08-31 23:58:57

我最近读了Neil Griffin的这篇文章,在不同类型的JSF托管豆之间做出区分,它让我思考了我自己的应用程序中不同豆子之间的区别。要快速总结要点:

  • 模型托管 Bean:这种类型的托管 Bean 参与 MVC 设计模式的“模型”关注点。当你看到“模型”这个词时,想想DATA。JSF 模型 bean 应该是一个遵循 JavaBean 设计模式的 POJO,其中包含封装属性的 getters/setter。

  • 支持托管 Bean:这种类型的托管 Bean 参与 MVC 设计模式的“视图”关注点。支持 Bean 的目的是支持 UI 逻辑,并且与 JSF 视图或 Facelet 组合中的 JSF 表单具有 1::1 的关系。尽管它通常具有 JavaBean 样式的属性和关联的 getters/setter,但这些属性是 View 的属性,而不是底层应用程序数据模型的属性。JSF 支持 Bean 也可能具有 JSF actionListener 和 valueChangeListener 方法。

  • 控制器托管 Bean:这种类型的托管 Bean 参与 MVC 设计模式的“控制器”关注点。控制器 Bean 的用途是执行某种业务逻辑,并将导航结果返回到 JSF 导航处理程序。JSF 控制器 bean 通常具有 JSF 操作方法(而不是操作Listener 方法)。

  • 支持托管 Bean:这种类型的 Bean“支持”MVC 设计模式的“视图”关注点中的一个或多个视图。典型的用例是向 JSF h:selectOneMenu 提供一个 ArrayList,这些下拉列表出现在多个 JSF 视图中。如果下拉列表中的数据特定于用户,则 Bean 将保留在会话范围内。

  • 实用程序托管 Bean:这种类型的 Bean 为一个或多个 JSF 视图提供某种类型的“实用程序”函数。一个很好的例子可能是可以在多个Web应用程序中重用的FileUpload Bean。

这对我来说是有道理的,在过去的几个小时里,我一直在重构我的代码,并提出了以下关于用户登录的内容:

这是控制器托管 Bean 的一个示例。它是请求范围的,具有两个用于设置用户名和密码的 getter 和 setter,以及两种导航方法,以及 ,在成功登录时将用户导航到其专用区域,或在注销时返回到主页。AuthenticationControllerauthenticatelogout

是支持托管 Bean 的一个示例。它是会话范围的,并具有类的实例(当您未进行身份验证时将为空),具有 getter 和 setter,仅此而已。UserBeanUser

将此用户作为托管属性 ()。身份验证成功后,会将托管属性设置为具有用于登录的相应用户名的实际用户实例。AuthenticationController@ManagedProperty(value = "#{userController.user} private User user;AuthenticationController

任何新的bean也能够将用户作为托管属性获取并提取它们所需的数据,例如组成员身份,如果该类将具有组名的列表。User

这种方式是否是分离关切的适当方式?


答案 1

这是一个非常主观的问题。我个人不同意这篇文章,并发现它给初学者提供了非常糟糕的建议。


模型托管 Bean:这种类型的托管 Bean 参与 MVC 设计模式的“模型”关注点。当你看到“模型”这个词时,想想DATA。JSF 模型 bean 应该是一个遵循 JavaBean 设计模式的 POJO,其中包含封装属性的 getters/setter。

我绝对不会制造或称之为管理豆。只需将其设置为 .例如,DTO 或 JPA 。@ManagedBean@Entity


支持托管 Bean:这种类型的托管 Bean 参与 MVC 设计模式的“视图”关注点。支持 Bean 的目的是支持 UI 逻辑,并且与 JSF 视图或 Facelet 组合中的 JSF 表单具有 1::1 的关系。尽管它通常具有 JavaBean 样式的属性和关联的 getters/setter,但这些属性是 View 的属性,而不是底层应用程序数据模型的属性。JSF 支持 Bean 也可能具有 JSF actionListener 和 valueChangeListener 方法。

这样,您就可以继续复制和映射受管 Bean 中实体的属性。这对我来说毫无意义。如前所述,只需使实体成为托管 Bean 的属性,并让输入字段直接引用它,而不是 。#{authenticator.user.name}#{authenticator.username}


控制器托管 Bean:这种类型的托管 Bean 参与 MVC 设计模式的“控制器”关注点。控制器 Bean 的用途是执行某种业务逻辑,并将导航结果返回到 JSF 导航处理程序。JSF 控制器 bean 通常具有 JSF 操作方法(而不是操作Listener 方法)。

这几乎描述了 / 类。是否允许事件侦听器方法取决于它们是否特定于绑定到 Bean 的视图和/或是否依赖于 Bean 的状态。如果它们是,那么它们属于豆类。如果不是,那么它们应该是任何 FacesListener 接口的独立实现,但绝对不是托管 Bean。@RequestScoped@ViewScoped@ManagedBean


支持托管 Bean:这种类型的 Bean“支持”MVC 设计模式的“视图”关注点中的一个或多个视图。典型的用例是向 JSF h:selectOneMenu 提供一个 ArrayList,这些下拉列表出现在多个 JSF 视图中。如果下拉列表中的数据特定于用户,则 Bean 将保留在会话范围内。

好。对于应用程序范围的数据,如下拉列表,只需使用Bean,对于会话范围的数据,如登录用户及其首选项,只需使用一个。@ApplicationScoped@SessionScoped


实用程序托管 Bean:这种类型的 Bean 为一个或多个 JSF 视图提供某种类型的“实用程序”函数。一个很好的例子可能是可以在多个Web应用程序中重用的FileUpload Bean。

这对我来说并不真正有意义。支持豆通常与单个视图相关联。这听起来太像 ActionListener 实现了,它将在命令组件中使用到你的选择。绝对不是受管理的豆子。<f:actionListener>

有关正确方法的启动示例,另请参阅:


答案 2

推荐