1.Webx总体介绍及使用场景
Webx是什么?
Webx是一套基于Java Servlet API的通用Web框架。它在Alibaba集团内部被广泛使用。从2010年底,向社会开放源码。
2001年,阿里巴巴内部开始使用Java Servlet作为WEB服务器端的技术,以取代原先的Apache HTTPD server和mod_perl的组合。
2002年,选择Jakarta Turbine作为WEB框架,并开始在此之上进行扩展。
2003年,经过大约一年的扩展,框架开始成熟。我们私下称这个经过改进的Turbine框架为Webx 1.0。
2004年,借着淘宝网的第一次改版,我们正式推出了Webx 2.0。由于Turbine开源项目发展过于缓慢,我们不得不放弃它。Webx 2.0是从零开始完全重写的,仅管它仍然延续了Turbine的使用风格。
2004年11月,Webx 2.0和Spring框架整合。
从那以后,Webx 2.0一直在进化,但没有作根本性的改动。
2010年,Webx 3.0发布。Webx 3.0抛弃了Webx 2.0中过时的、从Turbine中发展而来的Service框架,直接采用Spring作为其基础,并对Spring作了重大改进。Webx 3.0完全兼容Webx 2.0的代码,只需要修改配置文件就可完成升级。
2010年底,Webx 3.0开源。
现在有很多Java的Web框架可供选择,并且它们也都是免费的。例如,
Struts - http://struts.apache.org/
Webwork - http://www.opensymphony.com/webwork/
Tapestry - http://tapestry.apache.org/
Spring MVC - http://www.springsource.org/
⋯⋯
以上框架都是非常优秀的。说实话,如果阿里巴巴网站在2001年开始,就有这么多可选择的话,无论选择哪一个都不会有问题。因为这些年来,所有的开源Web框架都在互相学习、并趋于相似。Webx也不例外,它吸收了其它框架的很多想法。因此,当你使用Webx的时候,你会觉得在很多方面,它和其它开源的框架非常类似。
我并不是说所有的框架都一样好,而是说只要假以时日,所有的框架在发展过程中,必然会积聚好的方面,淘汰坏的方面,从而变得足够好。从这个角度看,的确没有特别明显的理由来选择Webx,但也没有明显的理由不选择Webx。
另一方面,由于每一种框架采用不同的设计,必然会有各自的优势。Webx也是如此 —— 它在某些方面有一些独到的设计,超越了同类框架。Webx有哪些优势呢?
Webx的优势
成熟可靠性
设计理念
应用框架(Application Framework),让人联想到建筑的框架(Frame Structure)。
建筑框架确定了整个建筑的结构;应用框架确定了应用的结构。
建筑框架允许你在不改变结构的基础上,*改变其内容。例如,你可以用墙体随意分隔房间。应用框架允许你在不改变整体结构的基础上,*扩展功能。
可以这样说,框架的本质就是“扩展”。*这样定义描写“软件框架”,它说一个软件框架必须符合如下要素:
Inversion of Control 反转控制 | 应用的流程不是由应用控制的,而是由框架控制的。 |
Default Behavior 默认行为 | 框架会定义一系列默认的行为。 |
Extensibility 扩展性 | 应用可以扩展框架的功能,也可以修改框架的默认行为。 |
Non-modifiable Framework Code 框架本身不可更改 | 框架在被扩展时,自身的代码无须被改变。 |
在一个框架中,实现丰富的功能固然重要,然而更重要的是:建立良好的扩展机制。我们知道,Webx目前虽然欠缺一些流行的功能。然而Webx却有一个良好的扩展机制,来支持开发者增加新的功能。
纵观开源的Web框架,做得比较好的框架,都有一个共性 —— 它们并不是简单地实现Web应用所需要的功能(诸如Action、模板、表单验证等),而是把框架建立在另一个基础框架之上。这个基础框架的作用是:组装模块;提供扩展机制。建立在这种基础上的Web框架有很好的适应性和扩展性,可以应对Web应用不断变化和发展的需求。
早期的Turbine,建立在Service框架之上。
Webwork,建立在Xwork框架之上。
Tapestry,建立在HiveMind或Tapestry IOC框架之上。
早期的Struts 1.x由于没有一个轻量框架作为基础,因此很难扩展。而Struts 2.x使用了Webwork和Xwork,因此适用能力大为提高。
Spring MVC,建立在Spring框架之上。
一个Web框架的好坏,往往不是由它所实现的具体功能的好坏决定的,而是由其所用的基础框架的好坏决定的。
Webx建立在SpringExt的基础上 —— SpringExt是对Spring的扩展。Spring是当今主流的轻量级框架。SpringExt没有损失任何Spring的功能,但它能够提供比Spring自身更强大的扩展能力。
设计良好的模块,应该是层次化的。
例如,模块B扩展了模块A,同时被模块C扩展。这样就形成了A、B、C三个层次。
如图所示,层次之间有如下的关系:
上层定义规则,下层定义细节;(上层、下层也可称为内层、外层)
上层是抽象的,下层是具体的;
越上层,越稳定(越少改变);越下层,越易变。
依赖倒转(Dependency Inversion)。下层(具体)依赖上层(抽象),而不是上层依赖下层。
下层扩展上层时,不需要修改到上层的任何代码和配置。即符合开闭原则(Open-Closed Principle简称OCP – Open for extension, Closed for modification)。
每一层均可被替换。
层次化的设计,使软件中的每一个部分都可被增强或替换。
层次化不是自然而然的,而是需要精心的设计。设计一个层次化的组件,可以从下面几方面来考虑:
切分功能。每个组件专心做一件事。
分析哪些会改变,哪些不会改变。不变部分固化在组件中,可能会改变的部分抽象成接口,以便扩展。
考虑默认值和默认扩展。默认值和默认扩展应该是最安全、最常用的选择。对于默认值和默认扩展,用户在使用时不需要额外的配置。
Webx鼓励层次化的模块设计,而SpringExt提供了创建和配置层次化组件的机制。
很多用过Webx框架的人说起Webx,就想到:Webx如何处理页面、如何验证表单、如何渲染模板等等功能。事实上,这些只不过是Webx最外层、最易变、非本质的功能。
Webx框架不仅鼓励层次化设计,它本身也是层次化的。你既可以使用全部的Webx框架,也可以只使用部分的Webx框架。大体上,Webx框架可以划分成三个大层次,如图所示。
SpringExt:基于Spring,提供扩展组件的能力。它是整个框架的基础。
Webx Framework:基于Servlet API,提供基础的服务,例如:初始化Spring、初始化日志、接收请求、错误处理、开发模式等。Webx Framework只和servlet及spring相关 —— 它不关心Web框架中常见的一些服务,例如Action处理、表单处理、模板渲染等。因此,事实上,你可以用Webx Framework来创建多种风格的Web框架。
Webx Turbine:基于Webx Framework,实现具体的网页功能,例如:Action处理、表单处理、模板渲染等。
并非所有的开发者都需要使用Webx的全部。下面列举几种情形。
对于非Web应用和单元测试,但却想拥有Spring和SpringExt的功能,可以直接创建SpringExt容器:
例 1.1. 直接创建SpringExt容器
import java.io.File; import org.springframework.core.io.FileSystemResource; import com.alibaba.citrus.springext.support.context.XmlApplicationContext; ... XmlApplicationContext parentContext = new XmlApplicationContext( new FileSystemResource(new File(srcdir, "parent.xml"))); XmlApplicationContext context = new XmlApplicationContext( new FileSystemResource(new File(srcdir, "app.xml")), parentContext); Object mybean = context.getBean("mybean");
请注意代码所使用的 |
|
这行代码从一个配置文件中创建容器。 |
|
这行代码创建了一个子容器。多个子容器和父容器之间可组成一个树状级联的容器结构。在子容器中可以访问到所有父容器中的beans和服务,但反过来是不成立的。 |
非webx框架也可以使用SpringExt的全部功能。
例 1.2. 修改/WEB-INF/web.xml
,让非webx框架支持SpringExt
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd "> <!-- 初始化日志系统,装载/WEB-INF/log4j.xml或/WEB-INF/logback.xml --> <listener> <listener-class>com.alibaba.citrus.logconfig.LogConfiguratorListener</listener-class> </listener> <!-- 初始化Spring容器,装载/WEB-INF/webx.xml, /WEB-INF/webx-*.xml --> <listener> <listener-class>com.alibaba.citrus.webx.context.WebxContextLoaderListener</listener-class> </listener> <!-- 下面配置:Spring MVC、Struts的filter、servlet、mapping... --> …… </web-app>
也许你想做一个新的Web框架 —— 因为你并不想使用Webx Turbine中提供的页面处理的方案,但你仍然可以使用Webx Framework所提供的服务,例如:错误处理、开发模式等。
例 1.3. 修改/WEB-INF/webx.xml
,以创建新的WEB框架
这个方案非常适合作为一个新Web框架的起点 —— 免去了创建Servlet/Filter、初始化Spring容器、处理request/response等繁杂事务,并且完全支持SpringExt的所有功能,此外还包含了错误处理、开发模式等Webx Framework中的一切便利。
另一种以Webx Framework为基础的创建新框架的方法,是从pipeline入手。通过pipeline,理论上可以实现任何框架的功能。