【问题标题】:Making Distinctions Between Different Kinds of JSF Managed-Beans区分不同种类的 JSF 托管 Bean
【发布时间】:2011-11-05 14:06:28
【问题描述】:

我最近阅读了 Neil Griffin Making Distinctions Between Different Kinds of JSF Managed-Beans 的这篇文章,它让我思考了我自己的应用程序中不同 bean 之间的区别。快速总结要点:

  • Model Managed-Bean:这种类型的 managed-bean 参与 MVC 设计模式的“模型”关注点。当你看到这个词 “模型”——想想数据。一个 JSF 模型 bean 应该是一个 POJO 封装了 getter/setter 的 JavaBean 设计模式 属性。

  • Backing Managed-Bean:这种类型的 managed-bean 参与 MVC 设计模式的“视图”关注点。一个目的 backing-bean是支持UI逻辑的,和有1::1的关系 JSF 视图或 Facelet 组合中的 JSF 表单。虽然它 通常具有与关联的 JavaBean 样式的属性 getter/setter,这些是视图的属性——而不是视图的属性 底层应用数据模型。 JSF backing-beans 也可能有 JSF actionListener 和 valueChangeListener 方法。

  • Controller Managed-Bean:这种类型的 managed-bean 参与 MVC 设计模式的“控制器”关注点。一个目的 控制器 bean 是执行某种业务逻辑并返回一个 JSF 导航处理程序的导航结果。 JSF 控制器-bean 通常有 JSF 操作方法(而不是 actionListener 方法)。

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

  • Utility Managed-Bean:这种类型的 bean 提供某种类型的 一个或多个 JSF 视图的“实用程序”功能。一个很好的例子 可能是一个可以在多个 web 中重用的 FileUpload bean 应用程序。

这对我来说很有意义,在过去的几个小时里,我一直在重构我的代码,并就用户登录提出了以下建议:

AuthenticationController 是控制器托管 Bean 的示例。它是请求范围的,具有两个用于设置用户名和密码的 getter 和 setter,以及两种导航方法,authenticate 和 logout,在成功登录时将用户导航到他们的私人区域,或者在成功登录时返回主页退出。

UserBean 是 Support Managed-Bean 的一个示例。它是会话范围的,并具有一个带有 getter 和 setter 的 User 类的实例(当您未通过身份验证时它为 null),仅此而已。

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

如果User 类具有包含组名的列表,那么任何新 bean 都可以将用户作为托管属性获取并提取他们需要的数据,例如组成员身份。

在关注点分离方面,这种方式是否正确?

【问题讨论】:

    标签: java jsf jakarta-ee backing-beans


    【解决方案1】:

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


    Model Managed-Bean:这种类型的 managed-bean 参与了 MVC 设计模式的“模型”关注点。当你看到“模型”这个词时——想想 DATA。 JSF model-bean 应该是一个 POJO,它遵循 JavaBean 设计模式,getter/setter 封装了属性。

    我绝对不会制作或称它为托管 bean。只需将其设为@ManagedBean 的属性即可。例如 DTO 或 JPA @Entity。


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

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


    Controller Managed-Bean:这种类型的 managed-bean 参与了 MVC 设计模式的“控制器”关注点。控制器 bean 的目的是执行某种业务逻辑并将导航结果返回给 JSF 导航处理程序。 JSF 控制器 bean 通常具有 JSF 操作方法(而不是 actionListener 方法)。

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


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

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


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

    这对我来说没有意义。支持 bean 通常与单个视图相关联。这听起来太像ActionListener 实现,<f:actionListener> 将在您选择的命令组件中使用它。绝对不是托管 bean。

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

    【讨论】:

    • 感谢 BalusC!我想我需要摆脱这样的想法,即以某种方式组织项目有严格的规则,并且更加务实,而不是沉迷于此类文章,强迫自己遵守。
    • +1 我不能对这个答案给予足够的支持!我读了一百遍同一篇文章,并花了一些时间试图听从它的建议,直到我放弃了,因为重复这么多东西对我来说没有意义......
    • 感谢 BalusC。最初这篇文章是有道理的,因为我是 JSF 的新手,但是在玩弄了我的 bean 之后,你的更新更有意义了。
    • 我们今天遇到了这个问题,@BalusC,我在谷歌搜索解释时找到了你的答案。我不同意文章的观点,但我实际上无法理解你的观点。恕我直言,ManagedBeans 位于视图和模型之间,而 FacesServlet 是控制器。但我很想知道你的意见。
    猜你喜欢
    • 2023-03-05
    • 2016-07-09
    • 2012-10-13
    • 2011-07-10
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多