我最近阅读了Neil Griffin撰写的这篇文章Making Distinctions Between Different Kinds of JSF Managed-Beans,它让我想到了我自己的应用程序中不同bean之间的区别。快速总结一下要点:
Model Managed-Bean:这种类型的托管bean参与了 MVC设计模式的“模型”关注点。当你看到这个词 “模型” - 想想数据。 JSF模型bean应该是后面的POJO 封装getter / setter的JavaBean设计模式 属性。
支持Managed-Bean:这种类型的托管bean参与了 “视图”关注MVC设计模式。一个目的 backing-bean是支持UI逻辑,与之有1:1的关系 一个JSF视图,或一个Facelet组合中的JSF表单。虽然它 通常具有关联的JavaBean样式属性 getters / setters,这些是View的属性 - 而不是 底层应用数据模型。 JSF支持bean也可能有JSF actionListener和valueChangeListener方法。
Controller Managed-Bean:这种类型的托管bean参与其中 MVC设计模式的“控制器”问题。一个目的 controller bean是执行某种业务逻辑并返回一个 导航结果到JSF导航处理程序。 JSF控制器bean 通常有JSF操作方法(而不是actionListener方法)。
支持Managed-Bean:这种类型的bean“支持”一个或多个视图 在“视图”中关注MVC设计模式。典型的用例 正在向JSF h提供一个ArrayList:selectOneMenu下拉列表 出现在多个JSF视图中的列表。如果数据在 下拉列表对用户来说是特定的,然后将保留bean 会议范围。
Utility Managed-Bean:这种类型的bean提供了某种类型的bean “实用程序”功能到一个或多个JSF视图。这是一个很好的例子 可能是一个可以在多个Web中重用的FileUpload bean 应用
这对我来说很有意义,过去几个小时我一直在重构我的代码,并提出了以下用户登录方式:
AuthenticationController
是Controller Managed-Bean的一个示例。它是请求范围的,具有两个用于设置用户名和密码的getter和setter,以及两个导航方法authenticate
和logout
,用户在成功登录后导航到其私有区域,或者返回到退出时的主页面。
UserBean
是支持托管Bean的示例。它是会话范围的,并且具有User
类的实例(当您未经过身份验证时将使用getter和setter,它将为null),仅此而已。
AuthenticationController
将此用户作为托管属性(@ManagedProperty(value = "#{userController.user} private User user;
)。身份验证成功后,AuthenticationController
会将托管属性设置为实际用户实例,并使用用于登录的相应用户名。
如果User
类具有包含组名的列表,那么任何新的bean都可以将用户作为托管属性获取并提取他们需要的数据,例如组成员资格。 / p>
关于分离问题,这种方式是否正确?
答案 0 :(得分:88)
这是一个非常主观的问题。我个人不同意这篇文章,发现它给初学者提供了非常糟糕的建议。
Model Managed-Bean:这种类型的托管bean参与了MVC设计模式的“模型”关注。当你看到“模型”这个词时 - 想想数据。 JSF模型bean应该是遵循JavaBean设计模式的POJO,其中getter / setter封装属性。
我绝对不会将其称为托管bean。只需将其设为@ManagedBean
的属性即可。例如,DTO或JPA @Entity
。
支持托管Bean:这种类型的托管bean参与了MVC设计模式的“视图”关注。 backing-bean的目的是支持UI逻辑,并且与Facef组合中的JSF视图或JSF表单具有1 :: 1的关系。虽然它通常具有带有关联getter / setter的JavaBean样式属性,但它们是View的属性 - 而不是底层应用程序数据模型的属性。 JSF支持bean也可能有JSF actionListener和valueChangeListener方法。
这样,您可以在托管bean中复制和映射实体的属性。这对我来说毫无意义。如上所述,只需将实体作为托管bean的属性,并让输入字段直接引用它,如#{authenticator.user.name}
而不是#{authenticator.username}
。
Controller Managed-Bean:这种类型的托管bean参与MVC设计模式的“Controller”关注。控制器bean的目的是执行某种业务逻辑并将导航结果返回给JSF导航处理程序。 JSF控制器bean通常具有JSF操作方法(而不是actionListener方法)。
这几乎描述了@RequestScoped
/ @ViewScoped
@ManagedBean
课程。是否允许事件侦听器方法取决于它们是否特定于与bean绑定的视图和/或它们的作业是否依赖于bean的状态。如果是,那么它们属于豆。如果没有,那么它们应该是任何FacesListener
interface的独立实现,但绝对不是托管bean。
支持Managed-Bean:这种类型的bean“支持”MVC设计模式的“View”关注中的一个或多个视图。典型的用例是向JSF h:selectOneMenu下拉列表提供一个ArrayList,它出现在多个JSF视图中。如果下拉列表中的数据特定于用户,则bean将保留在会话范围内。
精细。对于像下拉列表这样的应用程序范围的数据,只需使用@ApplicationScoped
bean,对于登录用户及其首选项等会话范围的数据,只需使用@SessionScoped
。
实用程序Managed-Bean:这种类型的bean为一个或多个JSF视图提供了某种类型的“实用程序”功能。一个很好的例子可能是FileUpload bean,它可以在多个Web应用程序中重用。
这对我来说并不合理。支持bean通常与单个视图绑定。这听起来太像ActionListener
实现,<f:actionListener>
将在您选择的命令组件中使用它。绝对不是托管bean。
有关正确方法的启动示例,请参阅: