为JSF定做的应用程序框架(二)

xiaoxiao2024-05-08  26

与 Seam 关联 与典型的 JSF 配置过程相比,使用 Seam 开发受管 bean 非常容易。为了将 bean 暴露到 JSF 生命周期中,只需在类定义的上面添加一个简单的注释 @Name。然后,Seam 会负责控制组件的可见性和生命周期。最妙的是,不需要在 faces-config.xml 文件中定义这个 bean。 清单 4 显示了 @Name 注释以及 @DataModel、@DataModelSelection、@In、@Out 和 @Factory。这些注释使变量能够在视图模板和 Seam 组件之间双向流动。 在 Seam 用语中,这个动作被称作双射(bijection,即 bidirectional injection 的简称)。当注出(outject)属性数据时,视图可以通过名称找到它。在 postback 或者组件初始化时,数据被注入(inject)到一个组件中。后者是著名的控制反转(inversion of control,IOC)模式的一种实现,可用于连接委托对象。传统 IOC 与 Seam 的双射之间的主要不同点在于,双射使长期作用域中的组件可以引用短期作用域中的组件。可以进行这种连接是因为 Seam 在调用组件时(而不是启动容器时)解析依赖项。双射是有状态组件开发的基础。 显然,清单 4 中的 POJO bean 只是简单地演示了 Seam 的用法。随着本系列讨论的继续,我将探索另外的方法来实现 Seam。 清单 4. 一个典型的 Seam POJO bean @Name("addressManager") public class AddressManagerBean { @DataModel private List<Address> addresses; @DataModelSelection @Out( required = false ) private Address selectedAddress; @Factory( value = "addresses" ) public void loadAddress() { // logic to load addresses into this.addresses } public String showDetail() { // no work needs to be done to divpare the selected address return "/address.jspx"; } public String list() { return "/addresses.jspx"; }} Spring 的注入 为了使用由一个已有的 Spring 容器管理的服务层对象中的投资,需要将所有处理相关业务逻辑的 Spring bean 注入到 Seam 组件中。首先需要确保已经配置了 Spring-JSF 集成,它由 Spring 框架附带的一个定制变量解析器进行处理(见 参考资料)。有了这座桥梁,Spring 与 Seam 的集成就很简单,只需使用 @In Java 5 注释和一个值绑定表达式,以表明 Seam 组件的哪些属性应该接收一个 Spring bean 的注入,如清单 5 所示。(将来版本的 Seam 将包括用于 Spring 的一个定制的名称空间,以满足值绑定表达式的需要。) 清单 5. 注入一个 Spring bean @Name("addressManager") public class AddressManagerBean { @In("#{addressService}") private AddressService addressService; } 这个例子设置支持使用以轻量级容器(这里就是 Spring)配置的无状态服务和数据访问(DAO)层。因为不需要 EJB3,所以部署的目标可以是任何基本的 servlet 容器。 现在,您对 Seam-JSF 实现有了一个初步的印象,接下来我将更深入地探讨我在使用 JSF 时遇到的挑战,以及 Seam 如何缓解这些挑战。 再谈 JSF 为了充分理解 Seam 为 JSF 带来了什么,就需要理解 JSF 与其他流行的基于 Web 的编程方法有何不同。JSF 是实现传统的 Model-View-Controller (MVC) 架构的一种 Web 框架。不同之处在于,它采用该模式的一种特别丰富的实现。与 Model 2 或者 Struts、WebWork 和 Spring MVC 之类的框架中使用的 “push-MVC” 方法相比,JSF 中的 MVC 实现更接近于传统的 GUI 应用程序。前面那些框架被归类为基于动作的(action-based),而 JSF 则属于基于组件模型 的新的框架家族中的一员。 如果将基于动作的框架想象为使用 “push” 模型,而将组件框架想象为使用 “pull” 模型,那么这种区别就很容易理解了。组件框架中的控制器不是预先处理页面请求(在基于动作的框架中控制器就是这么做的),而是在请求生命周期中作出让步,在视图中调用数据提供方法。此外,页面上的元素,即组件被绑定到事件,这些事件可以触发服务器端对象(激活后)的方法调用,从而导致重新显示相同的视图,或者转换到另一个页面。因此,组件框架也被归类为事件驱动的。组件框架抽象出用于事件通信的底层请求-响应协议。 事件驱动方法的优点是可以减少单个方法在呈现视图时需要预先做的工作。在组件框架中,UI 事件或解析的值绑定表达式直接导致方法调用。 一个应用程序即使只达到中度成熟,它通常也需要在任何给定页面上使用很多不相关的活动。如果将对所有这些信息的管理全部放入一个动作或者一个动作链中,那么势必给维护带来极大的困扰。因此,开发人员常常发现他们的代码偏离了面向对象模型的轨道,反而陷入了过程编程模型的泥潭。相反,组件框架将这种工作隔离出来,更自然地加强了对象的角色和责任。 Seam 与 JSF 对于 JSF 和组件框架的基础已经介绍得差不多了。实际上 —— 很多 Java 开发人员最近发现 —— 转移到 JSF 并非总是一帆风顺。采用组件模型会带来一些全新的问题,首要的一个问题是您通常需要试着使应用程序符合基于动作的 Web。很多时候,JSF 需要具有像基于动作的框架那样的行为,但是在标准 JSF 中这是不可行的,至少不为每个请求使用 phase 监听器就不行。 JSF 的其他主要缺点还包括对 HTTP 会话的依赖过重(尤其是在一序列的页面之间传播数据时),简陋的异常处理,缺少书签支持,以及太多的 XML 配置。通过与 JSF 自然地集成,同时加入 JSF 规范委员会放弃的或者忽略掉的新功能,Seam 解决了很多这样的问题。Seam 的框架鼓励使用紧凑的、易读的、可重用的代码,并且避免了所有为解决上述问题而常常加入的 “粘连(glue)” 逻辑。图 3 涵盖了 JSF 生命周期中用于简化应用程序代码的大多数 Seam 扩展点: 图 3. Seam 生命周期增强 [img]http://img.68design.net/art/images/laHd053XPyD8dlI.jpg[/img] 让我们来考虑其中一些增强,因为它们适用于 JSF 开发中一些常见的挑战。 并不复杂的配置 Seam 演示了 Java 5 注释的一个非常实用的用法。Seam 的部署扫描程序检查所有包含 seam.properties 文件的归档文件,并为所有标有 @Name 注释的类创建一个 Seam 组件。由于 Java 语言缺乏用于在代码级添加元数据的一种公共语法,因此需要设计很多 XML 配置。当 Java 5 规范中加入注释后,就获得了一个更好的解决方案。由于大多数 backing bean 是为了在特定应用程序中使用而开发的,因此没有理由将这些 bean 的配置 “抽象” 到类本身以外的任何文件中。附带的好处是,您可以少处理一个文件。Seam 提供了一组完整的注释来帮助将 bean 集成到 JSF 生命周期中。清单 4 显示了其中一些。 页面动作和 RESTful URL 在不使用组件框架的情况下,另一个必须解决的熟悉的问题是预先处理每个请求,就像在基于动作的框架中那样。受此影响的用例是 RESTful URL、书签支持、通过 URL 模式获得的安全性以及页面流验证等。这也是学习使用 JSF 的开发人员容易感到困惑的主要原因之一。有些 JSF 供应商通过用开发人员工具提供 onPageLoad 功能来绕过这个问题(见 参考资料),但这不是核心规范的一部分。 当用户直接从书签(比如)请求一个商品详细信息屏幕时,通常会发生什么事情呢?由于 JSF 控制器采取被动方式,当页面开始呈现时,即使明显没有目标数据,也不能将用户重新带到逻辑流的开始处。相反,这种情况下只能显示一个空页面,其中只有一些空值或其他可能存在的假信号。 首先,您可能会本能地想要在页面的主 backing bean 上实现一个 “divrender” 方法。然而,在组件框架中,backing bean 与页面之间的关系并不一定都是一对一的。每个页面可能依赖于多个 backing bean,每个那样的 bean 也可能在多个不同的页面上使用。必须用某种方式将一个视图 ID(例如 /user/detail.jspx)与一个或多个方法关联起来,当选择呈现相应的视图模板时就调用这个(些)方法。您可以使用 phase-listener 方法,但是这仍然需要定制的逻辑来确定对于当前视图和阶段是否应该执行该功能。这种解决方案不但会导致很多冗余逻辑,而且会将视图 ID(很可能是应用程序中最不确定的部分)硬编码到编译后的 Java 代码中。 相关资源:敏捷开发V1.0.pptx
转载请注明原文地址: https://www.6miu.com/read-5015227.html

最新回复(0)