区分不同种类的JSF托pipe豆

我最近阅读了Neil Griffin的这篇文章,对不同种类的JSF Managed-Beans进行了区分,这让我想起了我自己的应用程序中不同bean之间的区别。 要快速总结这个要点:

  • Model Managed-Bean:这种types的托pipebean参与了MVCdevise模式的“Model”关注。 当你看到“模型”这个词 – 想想DATA。 JSF模型bean应该是一个遵循JavaBeandevise模式的POJO,使用getter / setter封装属性。

  • 备份Managed-Bean:这种types的托pipebean参与了MVCdevise模式的“View”关注。 支持bean的目的是支持UI逻辑,并且与JSF视图或Facelet组合中的JSF表单具有1 :: 1的关系。 虽然它通常具有与关联的getter / setter相关联的JavaBean样式的属性,但它们是View的属性 – 而不是底层的应用程序数据模型的属性。 JSF支持bean也可能有JSF actionListener和valueChangeListener方法。

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

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

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

这对我有意义,在过去的几个小时里,我一直在重构我的代码,并提出了以下有关用户login:

AuthenticationController是Controller Managed-Bean的一个例子。 它是请求范围的,具有设置用户名和密码的两个获取者和设置者,以及两种导航方法: authenticatelogout ,成功login时将用户导航到其私有区域,或者在注销时返回到主页面。

UserBean是Support Managed-Bean的一个例子。 它是会话范围的,并且具有一个User类的实例(当你没有通过身份validation时它将是空的)和一个getter和setter,仅此而已。

AuthenticationController将这个用户作为一个托pipe属性( @ManagedProperty(value = "#{userController.user} private User user; ))。validation成功后, AuthenticationController会将托pipe属性设置为实际用户实例,用于login。

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

这样才能成为分离问题的正确方法吗?

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


Model Managed-Bean:这种types的托pipebean参与了MVCdevise模式的“Model”关注。 当你看到“模型”这个词 – 想想DATA。 JSF模型bean应该是一个遵循JavaBeandevise模式的POJO,使用getter / setter封装属性。

我绝对不会把它叫做托pipebean。 只要使它成为@ManagedBean一个属性。 例如DTO或JPA @ @Entity


备份Managed-Bean:这种types的托pipebean参与了MVCdevise模式的“View”关注。 支持bean的目的是支持UI逻辑,并且与JSF视图或Facelet组合中的JSF表单具有1 :: 1的关系。 虽然它通常具有与关联的getter / setter相关的JavaBean样式的属性,但它们是View的属性 – 而不是基础应用程序数据模型的属性。 JSF支持bean也可能有JSF actionListener和valueChangeListener方法。

这样你就可以不断复制和映射托pipebean中实体的属性。 这对我来说没有意义。 如上所述,只要使实体成为托pipebean的属性,并让input字段直接引用它,如#{authenticator.user.name}而不是#{authenticator.username}


控制器托pipeBean:这种托pipebean参与了MVCdevise模式的“控制器”关注。 控制器bean的目的是执行某种业务逻辑,并将导航结果返回给JSF导航处理程序。 JSF控制器bean通常具有JSF操作方法(而不是actionListener方法)。

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


支持Managed-Bean:这种types的bean在MVCdevise模式的“View”关注中“支持”一个或多个视图。 典型的用例是将ArrayList提供给出现在多个JSF视图中的JSF h:selectOneMenu下拉列表。 如果下拉列表中的数据是用户特有的,那么这个bean将被保存在会话范围内。

精细。 对于像下拉列表这样的应用程序范围的数据,只需使用@ApplicationScoped bean,对于会话范围的数据,如login用户及其首选项,只需使用@SessionScoped


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

这对我来说并不真实。 备份豆通常绑在单一的意见。 这听起来太像一个ActionListener实现,它将被命令组件中的<f:actionListener>用于您的select。 绝对不是托pipe的bean。

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

  • 我们的JSF wiki页面中的Hello World示例
  • “书店CRUD”这个答案的例子
  • 这个答案中的“主 – 细节”示例
  • JSF服务层
  • JSF中的通信2
Interesting Posts