本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接
Debug 笔记 <区分不同种类的JSF托管Bean>
提问
我最近阅读了Neil Griffin的《区分不同类型的JSF托管豆》中的这篇文章,
这使我开始思考自己的应用程序中不同bean之间的区别。快速总结要点:
Model Managed-Bean:这种类型的Managed-Bean参与MVC设计模式的“模型”关注。当您看到“模型”一词时,请考虑一下数据。JSF模型bean应该是遵循JavaBean设计模式且具有getters / setter封装属性的POJO。
支持Managed-Bean:这种类型的Managed-Bean参与MVC设计模式的“视图”关注。支持bean的目的是支持UI逻辑,并且与JSF视图或Facelet组合中的JSF表单具有1 :: 1的关系。尽管它通常具有带有关联的getter / setter的JavaBean样式的属性,但它们是View的属性,而不是基础应用程序数据模型的属性。JSF支持bean也可以具有JSF actionListener和valueChangeListener方法。
控制器受管Bean:这种类型的受管Bean参与了MVC设计模式的“控制器”关注。控制器bean的目的是执行某种业务逻辑并将导航结果返回给JSF导航处理程序。JSF控制器bean通常具有JSF动作方法(而不是actionListener方法)。
支持托管的Bean:这种类型的Bean在MVC设计模式的“视图”方面“支持”一个或多个视图。典型的用例是向JSF h:selectOneMenu下拉列表提供一个ArrayList,这些列表出现在多个JSF视图中。如果下拉列表中的数据是特定于用户的,则Bean将保留在会话范围内。
实用程序托管Bean:这种类型的Bean为一个或多个JSF视图提供某种类型的“实用程序”功能。一个很好的例子就是FileUpload bean,它可以在多个Web应用程序中重用。
这对我来说很有意义,并且在过去的几个小时中,我一直在重构代码,并针对用户登录提出了以下建议:
这AuthenticationController是Controller Managed-Bean的示例。它是请求范围的,具有两个用于设置用户名和密码的获取器和设置器,以及两个导航方法,authenticate和logout,在成功登录后将用户导航到其专用区域,或在注销时将其导航到主页。
这UserBean是Support Managed-Bean的示例。它是基于会话的,并具有一个User具有getter和setter的类的实例(在未通过身份验证时为null)的实例,仅此而已。
该AuthenticationController有这个用户作为托管属性(@ManagedProperty(value = "#{userController.user} private User user;)。身份验证成功后,AuthenticationController会将托管属性设置为具有用于登录的相应用户名的实际用户实例。
如果User该类具有包含组名的列表,那么任何新bean都将能够将用户作为托管属性,并提取所需的数据,例如组成员身份。
这样就可以解决关注点分离问题吗?
回答
这是一个非常主观的问题。我个人不同意该文章,并发现它给初学者提供了非常不好的建议。
Model Managed-Bean:这种类型的Managed-Bean参与MVC设计模式的“模型”关注。当您看到“模型”一词时,请考虑一下数据。JSF模型bean应该是遵循JavaBean设计模式且具有getters / setter封装属性的POJO。
我绝对不会制造或称其为托管bean。只要使其成为的属性即可@ManagedBean。例如DTO或JPA @Entity。
支持Managed-Bean:这种类型的Managed-Bean参与MVC设计模式的“视图”关注。支持bean的目的是支持UI逻辑,并且与JSF视图或Facelet组合中的JSF表单具有1 :: 1的关系。尽管它通常具有带有关联的getter / setter的JavaBean样式的属性,但它们是View的属性,而不是基础应用程序数据模型的属性。JSF支持bean也可以具有JSF actionListener和valueChangeListener方法。
这样,您就可以重复复制和映射托管Bean中实体的属性。这对我来说毫无意义。
如前所述,只需将实体设置为托管Bean的属性,然后让输入字段像#{authenticator.user.name}而不是直接引用它即可#{authenticator.username}。
控制器受管Bean:这种类型的受管Bean参与了MVC设计模式的“控制器”关注。控制器bean的目的是执行某种业务逻辑并将导航结果返回给JSF导航处理程序。JSF控制器bean通常具有JSF动作方法(而不是actionListener方法)。
这几乎描述了@RequestScoped/@ViewScoped @ManagedBean类。是否允许使用事件侦听器方法取决于事件侦听器方法是否特定于绑定到Bean的视图和/或是否依赖于Bean的状态来完成其工作。如果它们是,则它们属于bean。如果不是,那么它们应该是任何FacesListener接口的独立实现,但绝对不是托管bean。
支持托管的Bean:这种类型的Bean在MVC设计模式的“视图”方面“支持”一个或多个视图。典型的用例是向JSF h:selectOneMenu下拉列表提供一个ArrayList,这些列表出现在多个JSF视图中。如果下拉列表中的数据是特定于用户的,则Bean将保留在会话范围内。
对于应用程序范围的数据(如下拉列表),只需使用一个@ApplicationScopedbean;对于会话范围的数据,如登录的用户及其首选项,只需使用@SessionScoped一个。
实用程序托管Bean:这种类型的Bean为一个或多个JSF视图提供某种类型的“实用程序”功能。一个很好的例子就是FileUpload bean,它可以在多个Web应用程序中重用。
这对我来说真的没有意义。支持bean通常绑定到单个视图。这听起来太像是ActionListener要<f:actionListener>在命令组件中使用的实现方式,您可以根据自己的选择进行选择。绝对不是托管bean。
支持bean通常绑定到单个视图。这听起来太像是ActionListener要<f:actionListener>在命令组件中使用的实现方式,您可以根据自己的选择进行选择。绝对不是托管bean。
有关正确方法的启动示例,另请参阅:
文章翻译自Stack Overflow :stackoverflow.com/questions/7…