深入理解OSGi WEB应用程序规范和GlassFish OSGi/WEB容器
相关文章:GlassFish OSGi-JavaEE (一) GlassFish与企业级OSGi开发
http://www.bianceng.cnhttp://www.bianceng.cn/Programming/Java/201312/38601.htm
在Part1中,我们提到了企业级OSGi制定了一系列的规范来与JavaEE集成,其中,最具代表性的规范是OSGi WEB应用程序规范,这部分将带领大家深入理解OSGi WEB应用程序规范和GlassFish OSGi/WEB容器。本文将分成以下几个部分:
理解OSGi WEB应用程序规范
构建一个OSGi WEB应用程序
使用GlassFish 4部署OSGi WEB应用程序
深入剖析GlassFish OSGi/WEB容器
思考
理解OSGi WEB应用程序规范
为什么需要OSGi WEB
在信息和网络发达的今天,WEB应用程序已经非常得流行和普遍,一些任务关键型(Mission-Critical)的WEB应用程序每天都在高负荷地运行,很少有中断,因为一次不经意的中断可能造成数据的大规模丢失,以至损失大量的资金而造成严重的后果。这些任务关键型的WEB应用往往出现在证券和股票等相关的金融行业。现在,我们开始考虑一个场景: 几个星期或者几个月甚至几年后,WEB应用的客户或者提供商希望在WEB前端增加一些新的模块或功能,但是,为了增加这些新的模块,我们不能停止WEB应用,而且也不希望再次重构或者改变WEB应用的现有架构和模块。这听起来不可思议,对于这样一个场景,至少应该停止应用程服务的实例吧。但是,客户不会答应。另一方面,在当今大数据的时代,每一秒钟都会有大量的数据进入我们的应用之中。那么,如何解决这样的场景?
一个可行的答案是: 使用OSGi WEB构建我们的应用。
WAB-OSGi WEB的核心
简单地说,OSGi WEB应用程序规范(chapter 128 in the OSGi Enterprise Release 5 Specification[1])定义了OSGi WEB的全部内容。对于OSGi WEB应用程序,典型情况下,它由一个WEB应用程序Bundle(即Web Application Bundle,简称为WAB)所构成。
因此,首先我们需要理解WAB以及和WAR的区别。
WAB简述
在Part1中,我们已经提到Bundle是OSGi中的基本部署和管理实体。所以,WAB首先是一个Bundle,必须提供成为Bundle的OSGi元数据(如, Bundle-SymbolicName, Bundle-Version…),其次,WAB与JavaEE中的WAR一样,依然是服务于WEB应用程序,能够使用Servlet 2.5或更高版本的Servlet规范,因此,WAB必须包含可访问的WEB内容,具体的说,Java Servlet规范定义了一个WEB应用程序的结构并定义了一个基于JAR的文件格式(WAR),WAB必须包含WAR中的静态和动态的内容。
进一步地,要成为一个WAB,需要在MANIFEST.MF文件中通过Import-Package来描述它的依赖,例如: 通过导入javax.servlet来使用Servlet的功能,另外,如果需要向外界提供服务,它也要通过Export-Package来导出服务所在的包。
我们能够通过不同的方式来安装WAB,例如,通过支持企业级OSGi的应用服务器所提供的命令行控制台(如,GlassFish Admin CLI),也可以通过程序的方式调用OSGi底层API来安装WAB(如,BundleContext.installBundle)。无论哪一种方式,WAB安装后,它的生命周期管理就像OSGi运行时的其他Bundle一样。只不过WAB的生命周期被一个Web Extender跟踪,一旦WAB准备服务WEB请求时,Web Extender需要将WAB中可访问的WEB内容部署到WEB运行时。以后当WAB不再服务WEB请求时,Web Extender也需要将这些可访问的WEB内容从WEB运行时卸载掉。
关于WAB的安装,有一点需要额外说明,一个WEB应用程序能够在开发阶段通过工具(例如, Maven插件)被打包成WAB然后进行安装,或者这个WEB应用程序能够在Bundle安装阶段通过Web URL Handler对标准WAR进行转换来透明地创建WAB。GlassFish 4已经实现了后一种机制,我将在后续章节详细阐述。
关于Web Extender和Web URL Handler,它们都是OSGi WEB容器的一部分,我们将在后面章节详细阐述。
从上面的叙述,我们已经看到了安装WAB与安装普通Bundle的明显的不同之处: 除了安装WAB到OSGi运行时,还需要将WAB中可访问的WEB内容部署到WEB运行时。关于这一点,OSGi WEB应用程序规范定义了WAB的生命周期状态图,
图1: WAB的生命周期状态图
摘自: OSGi Enterprise Release 5 Specification
我们将在后续章节中深入阐述图1中的每个阶段。
WAB定义
WAB本身就是一个OSGi Bundle,因此,对于标准OSGi Bundle的定义同样适用于WAB,但是,WAB与标准OSGi Bundle本质的区别在于: WAB需要在MANIFEST.MF中定义Web-ContextPath属性。Web-ContextPath属性定义了这个WEB应用程序访问的上下文路径(Context Path)[2],在WEB服务器上,这个WEB应用程序中所有可访问的资源都要相对于这个上下文路径。例如, 如果在MANIFEST.MF定义了以下Web-ContextPath属性,
Web-ContextPath: /uas
那么访问这个WEB应用程序的URL总是相对于http://host:port/uas,需要注意的是: Web-ContextPath属性的值总是以斜杠’/’开始。
当安装WAB时,除非Web-ContextPath属性出现在MANIFEST.MF中且Web-ContextPath的值是一个有效的值,否则,Web Extender会认为这不是一个WAB,而视为一个普通的Bundle。