18. 同其他web框架集成

18.1 简介

本章详细介绍了Spring和其他第三方框架的集成,例如 JSF.

Sping框架的核心使命之一就是提供选择. 通俗说, Spring 不会强迫任何人去使用或者融入任何具体的架构、技术或者方法 (尽管它确实是会推荐一些给你). 这种在挑选架构、技术或者方法上的自由,是在web领域的开发者和开发团队成员之间争论时最显而易见 的, 当 Spring 推出它自己的web框架(Spring MVC)的时候, 同时也推出了同其他众多流行第三方web框架集成的方案. 这样就允许人们可以一方面享用由Spring带来的优势,例如数据访问、生命是事务管理以及灵活的配置和应用集成,同时继续使用以前很熟悉的 框架来发挥作用,例如JSF.

去掉那些推销的赞美之词(也就是前面那段),在这一章的剩余部分我们将专心地介绍如何将你喜爱的web框架同Spring集成起来. 一件经常被从 其他语言来学习Java的开发者提起的事就是Java貌似有大量的web框架可以用. 在Java世界里确实有很大数目的web框架;事实上,已经 多到了无法在一章里面全部涵盖完. 本章里面将选取Java web比较流行的4个框架,首先介绍Spring支持的所有框架的配置, 然后介绍 每一个web框架的配置的特别之处.

[Note]Note

请记住,本章不准备介绍怎样使使用支持的web框架. 例如, 如果你想使用JSF来作为你的前端展示层, 我们就假设你已经熟练于使用JSF本身了. 如果你想获取这些支持框架的更多内容,请查看本章末尾的Section 18.6, “更多资源”.

18.2 通用配置

在开始介绍每一个所支持的web框架的特有配置之前, 让我们先来看一下对每一个web框架来说都特殊的配置. (这部分配置也同样 适用于Spring自己的web框架, Spring MVC.)

对于(Spring)推崇的轻量级模型来说,一个概念(为了想一个更好的词)就是分层架构. 请记住,在传统分层架构中,web层只是许多层中的一层; 它只是作为服务端程序的入口来工作, 它把请求委托给服务层(表面上的)服务对象来满足定义好(并且与展示技术无关)的用例. 在Spring中, 所有的这些服务对象、业务定义对象、数据访问对象等等都存在于一个明确的业务上下文中, 这是一个 没有 web 或者展现层对象 (展现层对象,如Spring MVC的控制器,都是典型的配置在一个明确的展现上下文中). 这一节将向你展示怎样在一个应用的一个Spring 容器(一个WebApplicationContext)中包含所有的业务bean.

操作如下: 所有需要做的就是在一个web应用的web.xml文件中定义一个 ContextLoaderListener , 并且还要(在这个文件中)添加一个contextConfigLocation<context-param/> 节来指定哪些Spring的XML配置需要加载.

找到下面的<listener/>配置:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

找到下面的<context-param/>配置:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>

如果你没有指定contextConfigLocation的上下文参数, 那么ContextLoaderListener将会寻找并加载 一个名为/WEB-INF/applicationContext.xml的文件. 一旦上下文文件加载了, Spring就会根据bean的定义来创建一个 WebApplicationContext 对象并且将它存储在web应用的ServletContext中.

所有的Java web 框架都是构建在Servlet API之上的, 所以任何一个都可以通过下面的代码片段来访问由ContextLoaderListener 创建的业务上下文 ApplicationContext.

WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);

WebApplicationContextUtils 类来提供便利, 你就不需要记住ServletContext的属性了. 如果没有对应于 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE键的对象, 它的 getWebApplicationContext()方法会返回null. 相对简单粗暴地在你的应用中产生NullPointerExceptions, 最好使用getRequiredWebApplicationContext()方法, 这个方法会在ApplicationContext找不到的情况下抛出异常.

当你获得了WebApplicationContext的引用之后, 你就可以通过名字或者类型来获取bean. 大多数开发者都通过名字来获取bean, 然后转型为它所实现了的接口.

幸运的是, 大多数的框架在这里都有相似的方法来寻找bean. 他们不仅使得从 Spring容器中获取bean变得简单, 而且允许你在他们的控制器中 使用依赖注入. 每一款web框架在集成上都有更多的细节特性.

18.3 JavaServer Faces 1.2

JavaServer Faces (JSF) 是 JCP的标准的基于组件的, 事件驱动的web用户展现框架. 从 Java EE 5开始, 它就是 Java EE的官方正式组件之一.

选取http://myfaces.apache.org/[Apache MyFaces项目]作为流行的JSF运行时和流行的JSF组件库. MyFaces项目同样提供通用的JSF扩展例如 MyFaces Orchestra: 一个基于Spring的提供丰富的会话作用域支持的JSF扩展.

[Note]Note

Spring Web Flow 2.0通过新建立的Spring Faces组件提供丰富的JSF支持, 同时支持JSF-centric方式 (如本节介绍) 和Spring-centric方式(在Spring MVC控制跳转,使用JSF进行展现). 查看 Spring Web Flow站点 获取详细信息!

Spring与JSF集成的关键点在于JSF的ELResolver机制.

18.3.1 SpringBeanFacesELResolver (JSF 1.2+)

SpringBeanFacesELResolver 是一个与JSF 1.2 ELResolver相兼容的实现,与在JSF 1.2和JSP 2.1 中使用的标准统一EL集成. 就像SpringBeanVariableResolver, 它首先委托Spring的 业务上下文WebApplicationContext, 然后交给默认的底层JSF实现发现机制.

在你JSF 1.2的faces-context.xml文件中快速简单定义SpringBeanFacesELResolver的配置样例:

<faces-config>
    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
        ...
    </application>
</faces-config>

18.3.2 FacesContextUtils

尽管在faces-config.xml文件中将特性向bean映射的时候, 一个自定义的VariableResolver工作得很好, 但有时候人们需要明确地争夺bean. FacesContextUtils 这个类使得这一切很简单. 它和WebApplicationContextUtils很相像, 除了它需要一个FacesContext参数而不是一个 ServletContext参数.

ApplicationContext ctx = FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());

18.4 Apache Struts 2.x

由Craig McClanahan创建, Struts 是一个由Apache基金会管理的开源项目. 如今, 它大大地简化了JSP/Servlet编程样式并且赢得了大量的原先使用私有框架的开发者. 它简化了开发模型, 它开放源代码(于是就如同免费啤酒一样), 并且有一个相当大的社区, 它允许项目增长并且在Java web开发者中很流行.

查看Struts的 Spring Plugin 了解Struts 内建的对Spring集成的支持.

18.5 Tapestry 5.x

来自于 Tapestry 主页的信息:

Tapestry 是一个 "定位于创建动态的, 强壮的,高可扩展性的web应用的Java框架."

尽管Spring拥有他自己的强劲的web层, 但仍然有很多正当理由来使用一个用Tapestry作为用户展现层, 使用Spring容器来作为 更低层次的组合来构建企业级应用.

查看 同Spring集成模块获取更多信息.

18.6 更多资源

点击下面的链接来获取本章所提到的web框架的更多资源.