区别JSF中不同种类的Managed-Bean

 本文在实际应用中引起了我很多思考,也从中获益不少,特此转帖,此贴转自Aom社区,感谢译者Patrick Deng。

 

      JSF拥有一个简单的依赖注入(IoC)容器,称为JSF Managed Bean Facility(MBF)。虽然它具备了详细的XML配置语法,但并不及Spring BeanFactoryPicoContainer, 或JBoss Microcontainer等IoC容器那么壮健。MBF具有一个IoC容器的基本功能,提供了依赖注入等特性。

      在JSF MBF的管理之下的POJO通常都被称为Managed-Bean(托管Bean)。但如果你试图创建一个可维护的JSF Web应用(或portlet),你就需要区分开不同种类的Managed-Bean。这种做法同时也保证了在JSF中实现MVC模式的清晰分离概念。

 

 

Managed-Bean类型昵称典型的有效域
Model Managed-Beanmodel-beansession

描述: 这种类型的Managed-Bean充当MVC设计模式中的"模型(Model)"部分。当你看到"模型"一词————可以把它想象为"数据"。一个JSF的model-bean应该是一个遵循JavaBean规范的,以getter/setter方式封装了各种属性的普通JAVA对象。model-bean最常见的使用场景是作为一个数据库实体,或简单地代表了数据库查询结果集中的一系列行数据。

Backing Managed-Beanbacking-beanrequest

描述: 这种类型的Managed-Bean充当MVC设计模式中的"视图(View)"部分。backing-bean的目的是支持UI逻辑,(通常)与一个JSF视图或Facelet聚合中的JSF表单保持一一对应的关系。虽然它通常具有一些遵循JavaBean风格并关联了getter/setter的属性,但这些属性是对应"视图"中的值,而不对应底层的应用数据模型。JSF的backing-bean可以具有JSF的actionListener和valueChangeListener方法。

Controller Managed-Beancontroller-beanrequest

描述: 这种类型的Managed-Bean充当MVC设计模式中的"控制器(Controller)"部分。controller bean的目的是执行某些业务逻辑并返回一个导航结果给JSF的导航处理器。JSF controller-bean通常具有JSF的action方法(而不是actionListener方法)

Support Managed-Beansupport-beansession / application

描述: 这种类型的bean为MVC设计模式中的"视图(View)"部分中的一个或多个视图提供"支持"。典型的应用场景是提供一个ArrayList<SelectItem>给JSF的h:selectOneMenu下拉列表,而且这个下拉列表将在多个JSF视图中出现。如果这个下拉列表的数据是用户特定的,那么这个bean就应该放在session范围中。但是,如果数据是提供给所有用户的(例如一个选择省份的下拉列表),那么这个bean就应该放在application范围中。

Utility Managed-Beanutility-beanapplication

描述: 这种bean为一个或多个JSF视图提供"工具"。例如一个能在多个Web应用中复用的FileUpload bean。

 

 

     进行这种区分的一个主要好处是松耦合。你会问:这是虾米?那么,让我们先看一个紧耦合的例子,在这里MVC的概念被拼凑(或者说混淆)在单一的Managed-Bean中:

 

 

Java代码 
  1. public class ModelAndBackingAndControllerBean {  
  2.   
  3.     private String fullName; // model-bean property  
  4.     private boolean privacyRendered; // backing-bean property  
  5.   
  6.     // model-bean getter  
  7.     public String getFullName() {  
  8.         return fullName;  
  9.     }  
  10.       
  11.     // model-bean setter  
  12.     public void setFullName(String fullName) {  
  13.         this.fullName = fullName;  
  14.     }  
  15.   
  16.     // backing-bean getter  
  17.     public boolean isPrivacyRendered() {  
  18.         return privacyRendered;  
  19.     }  
  20.   
  21.     // backing-bean setter  
  22.     public void setPrivacyRendered(boolean privacyRendered) {  
  23.         this.privacyRendered = privacyRendered;  
  24.     }  
  25.   
  26.     // backing-bean actionListener for UI support logic  
  27.     public void togglePrivacySection(ActionEvent actionEvent) {  
  28.         privacyRendered = !privacyRendered;  
  29.     }  
  30.   
  31.     // controller-bean business logic  
  32.     public String submit() {  
  33.         System.out.println("fullName=" + fullName);  
  34.         return "success";  
  35.     }  
  36. }  

这种写法的问题是由于它充当model-bean,整个bean必须放在session范围。并且,当你想使用伪装的模型数据(mock model data)进行单元测试,你会发现根本行不通。因此为了修正这些问题,并实现松耦合,我们应该使用三个独立的Java类:

 

Java代码 
  1. public class ModelBean {  
  2.   
  3.     private String fullName;  
  4.   
  5.     public void setFullName(String fullName) {  
  6.         this.fullName = fullName;  
  7.     }  
  8.   
  9.     public String getFullName() {  
  10.         return fullName;  
  11.     }  
  12. }  
  13.   
  14. public class BackingBean {  
  15.   
  16.     private boolean privacyRendered;  
  17.   
  18.     public void setPrivacyRendered(boolean privacyRendered) {  
  19.         this.privacyRendered = privacyRendered;  
  20.     }  
  21.   
  22.     public boolean isPrivacyRendered() {  
  23.         return privacyRendered;  
  24.     }  
  25.   
  26.     public void togglePrivacySection(ActionEvent actionEvent) {  
  27.         privacyRendered = !privacyRendered;  
  28.     }  
  29.   
  30. }  
  31.   
  32. public class ControllerBean {  
  33.   
  34.     private ModelBean modelBean;  
  35.       
  36.     public ModelBean getModelBean() {  
  37.         return modelBean;  
  38.     }  
  39.   
  40.     public void setModelBean(ModelBean modelBean) {  
  41.         // Dependency injected from the JSF managed-bean facility  
  42.         this.modelBean = modelBean;  
  43.     }  
  44.   
  45.     public String submit() {  
  46.         System.out.println("fullName=" + getModelBean().getFullName());  
  47.         return "success";  
  48.     }  
  49.   
  50. }  

 

 

    现在这些bean实例将属于不同的类,可以分别保持在合适的有效域中。model-bean可以放在session范围,backing-bean和controller-bean可以放在request范围,因而节省了服务器的内存资源。

    最后,我们可以使用JSF MBF提供的依赖注入特性来把model-bean注入到controller-bean中。下面是WEB-INF/faces-config.xml配置文件示例,其中#{modelBean} EL表达式即为注入的配置:

 

 

Xml代码 
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"  
  4.     version="1.2">  
  5.     <managed-bean>  
  6.         <managed-bean-name>modelBean</managed-bean-name>  
  7.         <managed-bean-class>myproject.ModelBean</managed-bean-class>  
  8.         <managed-bean-scope>session</managed-bean-scope>  
  9.     </managed-bean>  
  10.     <managed-bean>  
  11.         <managed-bean-name>backingBean</managed-bean-name>  
  12.         <managed-bean-class>myproject.BackingBean</managed-bean-class>  
  13.         <managed-bean-scope>request</managed-bean-scope>  
  14.     </managed-bean>  
  15.     <managed-bean>  
  16.         <managed-bean-name>controllerBean</managed-bean-name>  
  17.         <managed-bean-class>myproject.ControllerBean</managed-bean-class>  
  18.         <managed-bean-scope>request</managed-bean-scope>  
  19.         <managed-property>  
  20.             <property-name>modelBean</property-name>  
  21.             <value>#{modelBean}</value>  
  22.         </managed-property>  
  23.     </managed-bean>  
  24. </faces-config>  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值