(计算机软件与理论专业论文)轻量型容器中开发j2ee+web应用的研究.pdf_第1页
(计算机软件与理论专业论文)轻量型容器中开发j2ee+web应用的研究.pdf_第2页
(计算机软件与理论专业论文)轻量型容器中开发j2ee+web应用的研究.pdf_第3页
(计算机软件与理论专业论文)轻量型容器中开发j2ee+web应用的研究.pdf_第4页
(计算机软件与理论专业论文)轻量型容器中开发j2ee+web应用的研究.pdf_第5页
已阅读5页,还剩72页未读 继续免费阅读

(计算机软件与理论专业论文)轻量型容器中开发j2ee+web应用的研究.pdf.pdf 免费下载

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

轻量型容器中开发j 2 e ew e b 应用的研究 计算机软件与理论专业 研究生:张进坤指导教师:谢汶副教授 j 2 e e 是当今用于企业软件开发的最佳平台之一。它结合了j a v a 编程语言的 各种优点和过去1 0 多年中企业软件开发中的种种教训。但是,对许多w e b 应用 程序来说,j 2 e e 没有显著的成功。传统的j 2 e e 体系结构的开发、部署和测试 都是复杂的。本文结合几种目前比较流行的技术,提出一种开发典型j 2 e e w e b 应用问题的良好解决方案,以帮助在预算内按时建立简单的、高质量的、维护 性好的、性能好的和扩展性好的j 2 e ew e b 应用程序。 首先,本文阐述了轻量型容器和反转控带u 0 0 c ) 的基本原理,比较了轻量型 容器相对于e j b 容器的优势;其次,本文调查了可选的j 2 e ew e b 应用的体系结 构,阐述每一种体系结构的优缺点:第三,本文从体系结构的角度详述了开发 j 2 e ew e b 应用时表示层、商业服务层和数据存取层的设计问题,和一些比较新 的技术,比如面向切面编程( a o p ) 和对象关系映射( o r m ) ,然后介绍了几种目 前比较流行的实现表示层、商业服务层和数据存取层的开源框架,比如s t r u t s 、 s p r i n g 和h i b e r n a t e 等;最后,本文运用这些技术实现了一种开发典型j 2 e ew e b 应用程序的简单方式。 关键字:j 2 e e ;轻量型容器;体系结构;i o ca o p ;o r m t h er e s e a r c ho f d e v e l o p i n gj 2 e ew e ba p p l i c a t i o ni nl i g h t w e i g h tc o n t a i n e r m a j o r :c o m p u t e rs o f t w a r ea n dt h e o r y p o s t g r a d u a t e :z h a n gj i n k u n a d v i s o r :x i ew e n n o w a d a y st h ej 2 e ep l a t f o r mi so n eo ft h eb e s ti ne n t e r p r i s es o t h a r es c o p e i t a b s o r b sv a r i o u sm e r i t st h a tj a v ap r o g r a m m i n gl a n g u a g ep o s s e s s e sa n dm u c hl e s s o n t h a te n t e r p r i s es o f t w a r ee n c o u n t e r si np a s tt e ny e a r s h o w e v e r , f o rm a n yw e b a p p l i c a t i o n s ,j 2 e eh a sn o tb e e nas h i n i n gs u c c e s s “c l a s s i c ”j 2 e ea r c h i t e c t u r e sa r e c o m p l e xt od e v e l o p ,d e p l o ya n dt e s t o nt h eb a s i so fs e v e r a lp o p u l a rt e c h n o l o g i e s , t h ea r t i c l eb r i n g sf o r w a r dag o o dw a yf o rd e v e l o p i n gt y p i c a lj 2 e ew e b a p p l i c a t i o n s t h a th e l p st op r o d u c es i m p l e ,h i g h - q u a l i t y , m a i n t a i n a b l e ,p e r f o r m a n t ,a n ds c a l a b l e a p p l i c a t i o n so nt i m ea n dw i t h i nb u d g e t f i r s t l y , t h ea r t i c l ee x p a t i a t e so nt h eb a s i cp r i n c i p l eo f l i g h t w e i g h tc o n t a i n e ra n d i n v e r s i o no fc o n t r o l ,a n dp o i n t so u ta d v a n t a g e sf o rl i g h t w e i g h tc o n t a i n e rc o m p a r e d w i t l le j bc o n t a i n e r ;s e c o n d l y , t h ea r t i c l es u r v e y sa l t e r n a t i v ea r c h i t e c t u r e sf o rj 2 e e l p p l i c a t i o n s ,f o c u s i n g o nw e ba p p l i c a t i o n s f o re a c ha r c h i t e c t u r e ,ic o n s i d e ri t s s t r e n g t h sa n dw e a k n e s s e s t h i r d l y , t h ea r t i c l ed w e l l so nd e s i g np r o b l e m so i lt h e p r e s e n t a t i o nl a y e r , t h eb u s i n e s sl a y e ra n dt h ed a t aa c c e s sl a y e rf r o ma r c h i t e c t u r a l p o i n to fv i e w , a n dr e c o m m e n d ss e v e r a ln e wt e c h n o l o g i e ss u c ha sa s p e c to r i e n t e d p r o g r a m m i n g ( a o p ) a n do b j e c t - r e l a t i o nm a p p i n g ( o r m ) ,t h e ni n t r o d u c e ss o m e p o p u l a ro p e ns o u r c ep r o d u c t ss u c ha ss t r u t s ,s p r i n ga n dh i b e r n a t e l a s t l y , t h ea r t i c l e r e a l i z e sas i m p l e rw a yf o rd e v e l o p i n gt y p i c a lj 2 e ew e ba p p l i c a t i o n s k e yw o r d s :j 2 e e ;l i g h t w e i g h tc o n t a i n e r ;a r c h i t e c t u r e ;i o c ;a o p ;o r m i i 四川大学硕士论文 第1 章引言 1 1 简介 j 2 e e 是当今可用于企业软件开发的最佳平台之一。它结合了j a v a 编程的多 种优点和过去1 0 多年中企业软件开发中的经验。但是,我们不能忽视,对许多 w e b 应用程序来说,j 2 e e 没有取得显著的成功。遗憾的失败和耀眼的成功可能 一样平常。在项目投资上,j 2 e e 项目经常显示较小的价值,大多数都超过预算; 在项目实施中,许多项目无法按期完成;在性能方面,许多应用程序达不到预 期性能,而且某些则完全不符合需求;其宣传的可靠性和可扩展性常常无法兑 现;与需求的复杂性相比,应用程序代码常常要复杂得多。 当然,上述这些问题中的一部分在其它软件技术中也存在( 有些是非技术 因素的结果) ,但是实践中的j 2 e e 的确在改进先前技术缺点上没有明显的成功, 反而添加了一些新的问题,这类问题一直是在公共会议上讨论的焦点。指出这 些令人不悦的事实,不是为了攻击j 2 e e ,而是为了更好的使用它。我认为造成 这些问题的原因主要有两个,它们中的每一个都反映了j 2 e e 作为一项技术的内 在缺陷: 1 ) 追求体系结构时尚:在设计j 2 e e 应用程序时,倾向于设计庞大、复杂 的体系结构。这是引起前述问题的主要原因。 2 ) 要求单一化基础结构:在基础结构之外使用j 2 e e 开发应用程序是很困 难的,这需要新的框架和类库来实现。 遵循传统的体系结构的规定,在实践中使用j 2 e e 的主要问题是它的复杂 性。在2 0 0 2 年初,j 2 e e 社区就已经指出了这个问题。传统的j 2 e e 解决方案忽 视了它,或者说希望依赖开发工具解决它。因为开发工具不可能有效的处理这 个问题,所以越来越多的开发人员希望降低开发j 2 e e 的复杂性,而不是使用权 宜的解决方案。然而,j 2 e e 是一个庞大的平台,它的复杂性意味着许多j 2 e e 应用程序很难维护、可靠性差、效率低下。开发人员必须花费大量的时间学习 复杂的a p i 和繁琐的程序模型,这常常导致较长的开发周期。e j b 出现的主要 目的是希望开发人员集中精力处理商业逻辑,然而,它不但没有成功,反而成 了这个问题中更复杂的一部分。 实际上,如何更好的使用j 2 e e 开发应用程序比使用它的基本建立块更加紧 四j i l 大学硕士论文 迫。j 2 e e 技术的主要建立块都是极好的,比如:j t a 、j n d i 、j d b c 和j a v a 语 言本身。没有任何相竞争的平台可以宣称,在开发企业应用方面有如此多标准 化的、并经过实践证明的建立块。当然,也有一些支撑j 2 e e 的j 2 e e a p i s 和j 2 s e a p i s 并不是最适合于开发人员使用的,例如,已经在实践中证明,如果能够在 j d b c 或者j t a 之上添加一个抽象层,那么可以显著的简化开发,降低出现错 误的可能性。即便如此,j 2 e e 平台通过提供一个一致的、完整的访问企业服务 的模型仍然体现了它的重要价值。 形势正逐渐地改善。现在,j 2 e e 应用程序服务器更加可靠,更加容易使用。 j a v a 开发工具也越来越成熟,比如e c l i p s e 、j b u i l d e r 、i n t e l l i j 这样的i d e 工具 和j u n i t 这样的测试工具,都为快速灵活的开发j 2 e e 应用提供了简单有效的支 持。再加上大量容易理解的j a v a 代码,所有这些都给开发人员提供了很大的帮 助。但是,j 2 e e 的核心问题j 2 e e 体系结构的传统开发方式引发的复杂设计, 一直没有得到明显地改善。 许多开发人员一直认为,j 2 e e 应用不应该是简单的。事实上,许多j 2 e e w e b 应用的需求简单,比如由一个关系型数据库支撑的相对简单的商业逻辑。这样 的应用不需要分布式对象那样的复杂性,它们甚至不需要使用j t a 提供分布事 务支持。它们只需要一个简单的、面向对象的解决方案。然而,这恰好是过于 复杂的实现不能解决的。 对任何应用程序来说,聚焦于需求比聚焦于技术更重要【2 6 1 。无论采用什么 技术,它都应该是达到目的的一种方式,而不应该决定描述需求的方法。由于 传统j 2 e e 解决方案的复杂性,许多j 2 e e 开发人员更加关注他们使用的技术, 有时甚至不惜把问题复杂化作为代价。相比起来,许多其它技术的开发人员很 少倾向于这种优先权的扭曲。 1 2 本文的目的 本文研究的主题正是基于这种背景下提出的,我认为应该有更简单的方法 设计大多数j 2 e ew e b 应用程序。 轻量型容器体系结构的概念是针对传统的j 2 e e 体系结构提出的。它克服了 许多传统j 2 e e 体系结构的缺点,引进了很多优点,是适合于大多数典型j 2 e e 应用的一种较好的体系结构,特别适合于j 2 e ew e b 应用。 四川大学硕士论文 在很多情况下,不需要完整j 2 e e 的各个层次。例如,如果一个应用程序只 需要存取单一的数据库,就没有必要使用j t a 。选择最简单可行的容器,可以 减少开发的复杂性,简化管理,付更少的l i e e n s e 费用,不需要高端的应用服务 器,这些都是有实际利益的。使用象s p r i n g 这样支持体系结构的框架,一个s e r v l e t 容器对大多数w e b 应用来说都是足够的。使用轻量型容器解决方案,应用的复 杂性与要解决问题的复杂性是成比例的,用户不需改变应用程序的代码就可以 在不同服务器下移植,这些都是传统的j 2 e e 开发方式不可能做到的。 本文的主要目的就是,寻找一种既要简单又更强大的下一代组件模型,为 开发人员提供一种可以解决典型j 2 e ew e b 应用问题的良好解决方案,使他们可 以在最快的时间内开发出简单、高效、稳定的j 2 e e w e b 应用。 1 3 本文所做的主要工作 本文所做的主要工作如下: 概述了j 2 e ew e b 应用开发的背景和现状。 阐述了轻量型容器和反转控制的基本原理,比较了轻量型容器相对于 e j b 容器的优势。 调查了可选的j 2 e ew e b 应用的体系结构,阐述了每一种体系结构的优 缺点。 从体系结构的角度详述了开发j 2 e ew e b 应用时表示层、商业服务层和 数据存取层的设计问题。 介绍了面向切面编程和对象关系映射技术,和几种目前比较流行的实 现表示层、商业服务层和数据存取层的开源框架,比如s t r u t s 、s p r i n g 和h i b e r n a t e 等。 在轻量型容器中实现了一个订购系统j 2 e ew e b 应用开发的简单示例。 1 4 本文的组织结构 全文共为8 章: 第1 章“引言”,介绍了使用轻量型容器开发j 2 e e w e b 应用的背景和现状, 指出了本文的主旨和文中所做的主要工作。 i 第2 章“轻量型容器和反转控制”,主要阐述了轻量型容器和反转控制的基 四川大学硕士论文 本原理,比较了轻量型容器相对于e j b 容器的优势。 第3 章“j 2 e e 体系结构”,调查了目前几种开发j 2 e ew e b 应用的体系结构, 从中可以看出轻量型容器体系结构的优势。 第4 章“表示层”,首先探讨了j 2 e e 体系结构中表示层的设计问题,然后 介绍几种实现表示层的技术,主要是j a k a r t as t r u t s 和其它目前比较流行的开源 框架。 第5 章“商业服务层”,首先探讨了j 2 e e 体系结构中商业服务层的设计问 题;然后介绍了a o p 技术;最后介绍了目前比较流行的轻量型容器,主要是 s p r i n g 和其它开源的轻量型容器。 第6 章“数据存取层”,首先详述了数据存取层在面向对象应用中的持久性 和范例不匹配问题,然后介绍了几种实现持久层的可选方案,最后介绍了o r m 技术,给出几种较流行的实现o r m 的持久性框架。 第7 章“在轻量型容器中开发j 2 e ew e b 应用实例”,使用本文介绍的轻量 型容器s p r i n g 和s t r u t s 、h i b e r n a t e 等开源框架实现了一个开发j 2 e ew e b 应用的 简单实例。 第8 章“结论及进一步展望”,归纳了本文的主旨,提出对未来的展望。 四j 1 1 3 学硕士论文 第2 章轻量型容器和反转控制 应用程序需要体系结构的支撑,管理商业对象需要某种形式的容器。当然, 不使用容器,没有完整的应用程序框架也能够开发j 2 e e 应用,但那种做法是愚 笨的,而且会导致重复使用单例模式、定制工厂模式【7 】,应用程序整体配置不 一致等。它也很难为应用确定一个清晰的商业服务层,缺乏一致性也会导致巨 大的维护成本。 目前在开发j 2 e e 应用领域存在两种容器。一种是e j b 容器,另外一种我 叫它轻量型容器( l i g h t w e i g h tc o n t a i n e r ) 。e j b 在一定程度上解决了不使用容器 开发应用程序时造成的混乱,它也提供了一种定义良好的服务层( 即s l s b ) , 但那只是部分的管理商业对象的解决方案。轻量型容器不但可以彻底解决上述 混乱,组织你的应用程序,更重要的是,它要比使用e j b 简单的多。 反转控制( i n v e r s i o no f c o n t r 0 1 ) 是一种良好的配置管理对象的方案。使用 i o c ,容器负责配置在其中运行的应用程序对象,不再需要写查询代码。当前比 较受欢迎的轻量型容器都支持某种形式的i o c 。 在本章中,我们将看到如何使应用程序代码最小化地依赖于容器。这是最 现实也是最重要的目标。我们将比较一下轻量型容器和e j b 容器的异同,还将 探讨反转控制。 2 1 什么是轻量型容器 我使用容器来指代应用程序代码运行的框架。应用程序对象,通常是商业 对象,在容器中运行,由容器来管理。有许多容器体系结构和模型,e j b 是传 统上最流行的在j 2 e e 领域中管理商业对象的容器。j 2 e ew e b 容器是专门用于 管理s e r v l e t 及依赖对象的例子。 任何容器都应该提供一个服务集,包括【i 】: 生命周期管理:容器应该能够控制在其内运行的应用程序对象的生命 周期。也就是说,容器应该能够从使用它的代码中抽象出新对象的创 建。更加灵活的管理生命周期的方式还应该包括回滚在容器中改变的 管理对象和回收容器资源。 查询定位:容器应该可以提供一种方式去获得在其内运行的管理对象 四川太学硕士论文 的引用。查询定位功能是容器应该提供的一项核心功能。 配置器:容器应该提供一致的方式配置在其内运行的对象,并且允许 对象参数化。应该从j a v a 代码中删除简单的配置值,以便在更改这些 值时不需要重新编译代码或影响j a v a 程序开发人员。 依赖解析:容器应该能够管理在其内运行的对象之间的关系。 容器也可以提供一些附加服务,这些服务应该独立于它的核心模型。 企业服务:为运行在容器内的对象提供事务管理或其它的声明式服 务。 线程管理:容器可以提供一个线程模型来存取管理对象。 对象池;容器可以为管理的对象提供实例池。 集群:容器本身提供集群支持,客户使用它可以和对等的容器透明地 通讯,类似e j b 集群那样。 管理服务:容器可以为运行在其内的对象提供管理服务,比如控制台 管理或通过j m x 来管理。 暴露远程服务:为运行在容器内的对象提供远程存取支持。远程e j b 是一种优秀的这方面的技术。 消费远程服务:提供透明地存取运行在容器外的远程对象。 定制性和扩展性:允许为运行在容器内的对象定制服务。例如,定制 声明式服务,比如特殊的安全检查。 轻量型容器是针对e j b 容器提出的,除了具有容器所有的特点外,它还具备 自己的特性: 容器可以管理应用程序代码,但又不对代码强加特定的依赖。例如, 应该可以在容器中毫无修改地运行遗留代码。这种容器通常也称为无 侵略性容器。如果没有特殊的需要,开发人员使用的基础结构不应该 对其代码强加任何侵略性的依赖。代码不应该依赖于某种容器,应该 可以在容器内和容器外运行相同的应用程序代码。 容器应该可以快速地启动。 容器不需要任何特殊的步骤来配置运行在其内的对象。 容器最小限度地依赖a p i ,可以在多种环境下运行,比如w e b 容器, s t a n d a l o n ec l i e n t ,甚至a p p l e t 。轻量型容器应该是基于j a v a 语言的,而 6 四川大学硕士论文 不应该是基于j 2 e e 的。 容器可以对加入其内的对象进行配置。就配置繁琐度和性能代价而 言,配置和管理细粒度对象应该同粗粒度对象是一样的,耗费同样低 的费用。 实际上,轻量型容器和e j b 容器是不同的。同e j b 容器的比较是理解轻量 型容器特点的最好方式。e j b 容器不符合轻薰型容器的标准: 为e j b 模型写的代码不能脱离e j b 容器运行。 e j b 容器的启动速度相对较慢。 配置e j b 相当繁琐,每个e j b 涉及很多的j a v a 源文件,还可能包括预 配置产生代码和编译步骤等。 e j b 代码只能在单一环境中运行。 e j b 不适用于细粒度对象。 e j b 容器也没有满足所有容器应该满足的标准: 依赖解析:e j b 容器没有提供对运行在其内的e j b 对象之间的关系管 理。它只不过是提供一个j n d i 上下文,e j b 代码使用它可以获得其它 的e j b ,这同任何其它的代码没有区别。甚至配置一个简单属性也是复 杂的,b e a n 的实现代码被迫使用j n d i 来寻找定义在冗长的x m l 配置 描述符文件中的环境变量。而且环境变量是无类型的,需要在e j b 代 码中寻找它们,然后强制转换。 消费远程服务:虽然e 1 b 容器通过使用r m i 或s o a p 对暴露远程服务 提供了极好的支持,但是它没有提供消费远程服务的支持。 定制性和扩展性:e j b 规范没有在e j b 容器中提供对组件定制服务的 支持。 无论e j b 在企业服务方面做的多好,它在作为容器模型方面做的的确较差。 考虑到e j b 的负面作用,寻找一种可以替代e j b 的容器模型也是合情合理的。 2 2 为什么需要容器 在追求简单性的时候,为什么不能除去容器的概念昵? 有许多原因可以说明容器是重要的。下面仅列出一些: 可拔插性:容器应该允许不同组件的可拔插性。例如,不同的e j b 实 四川大学硕士论文 现类可以使用相同的组件接口,从具体的实现策略上隔离代码。虽然 j a v a 提供了完美的方式分离接口和实现,但是必须要有一些方法来查询 想用一个接口的哪些实现。如果这种查询需要硬编码,那么就丧失了使 用接口的优势。 一致性:没有一致的基础结构,服务查询的方式将是随意的。开发人 员将会按照各自的喜好以不同的方式查询定位服务对象。应用程序的管 理配置也将是随意的。所有这些都对日后的维护工作提出更强的挑战。 一步到位:只要发现容器,就应该能够查找到它所提供的所有服务。 没有必要为每一个对象提供一个专门的单例模式或工厂模式。 传递企业服务:容器可以采用一致的方式传递企业服务。 2 3 轻量型容器v s e j b 如果在使用轻量型容器和e j b 容器之间可以选择的话,为什么开发人员要 选择轻量型容器呢? 下面来看看在典型j 2 e e 应用中轻量型容器和e j b 容器的正 反对比。 2 3 1 轻量型容器的优势 轻量型容器的一些优势体现在: 避开了集成式容器:e j b 容器是重量型容器。它提供了一种全有全无的 方式开发企业组件模型。如果不使用e j b 容器,能够传送企业服务到 典型w e b 应用,那么就可以简化体系结构。通常情况下,不使用高端 的应用服务器,可以做到这些。这不仅降低了成本,而且也减小了管理 的复杂性。例如,即使同时使用一种开源轻量型容器和一种商业w e b 容器,开发人员也可以选择w e b l o g i ce x p r e s s 来提供核心的j 2 e e 服务, 如j t a ,这要比使用支持e j b 的w e b l o g i e 版本便宜的多、简单的多。 最大限度地重用代码:使用e j ba p i 写的代码只能运彳亍在e j b 容器中。 这是难以令人满意的。 更大的面向对象空间。e j b 通常不是真正的对象,因为它们受限于e j b 组件模型的特性。例如,e j b 必须是相当粗粒度的,即使本地e j b 也是 如此。这限制了正规的o o 设计。虽然e j b 的实现类能够分享继承特 四川大学硕士论文 性,但是e j b 组件模型不支持继承。由于轻量型容器强加给对象的限 制要少的多,所以通常它们可以获得更大的面向对象空间。 更大的生产力。使用轻量型容器,应用程序代码可以更接近于普通的 j a v a 代码。它更少的依赖于重量型a p i ,在任何j a v a 的i d e 环境中都 更容易书写和操纵。 更好的测试性能。因为对象可以在任何容器外测试,测试性能也将大大 地提高。例如,使用普通的j u n i t 测试实例。 2 3 2e j b 的优势 e j b 的优势在于把企业服务和容器模型集成在一起。也就是说,e j b 是使 用声明式的中间件服务来管理商业对象和提供管理对象的一种简单的解决方 案。当然,在e j b 比较薄弱的领域,轻量型容器仍然是e j b 很重要的补充,比 如管理细粒对象。 此外,e j b 的优势主要体现在行政方面。例妇,e j b 有很大的动力,e j b 比较容易理解和e j b 市场相对稳定等。而轻量型容器的前景正在展开。 2 4 反转控制 我们已经提到避免应用程序代码依赖于容器的愿望,可是如何才能实现这 个愿望昵? 只有很简单的对象单独的工作,大多数商业对象之间存在依赖,比 如其它的商业对象、数据存取对象和资源等。可以肯定的是,对象需要查找其 它的管理对象和资源,这种需要只有依赖容器来满足。 反转控制和依赖注射( d e p e n d e n c y 刈e c t i o n ) 可以满足这种需要。它们不 需要引进对容器的依赖,就能够满意地查询定位其它的管理对象和资源。 一般来说,反转控制是框架领域的一个重要概念,它允许一个对象在上层 接受其它对象的创建。使用反转控制方式,可以让你的对象从创建中释放出来, 降低了耦合度。本论文的以下部分,我将用缩略词i o c 来代表反转控制。 图2 1 是个没有使用i o c 的对象创建的例子,它具有很高的的耦合度。 而图2 2 是一个使用了i o c 的例子,这种方式允许对象在高层可以创建并进 入另外一个对象,所以这样可以直接被执行。 9 四川大学硕士论文 图2 1 没有使用l o c ,对象a 创建了b 和c 。 图2 2 对象使用了i 0 0 ,对象 包含了b 、c 的s e t t e r 方法 这同样达到了由a 创建b 、c 的目的。 2 4 1i o c 的实现策略 i o c 是一个很广泛的概念,它可以通过许多不同的方式来实现。其中有两种 主要的实现方式 l 】= 1 ) 依赖查询:这是e j b 使用的方式。容器为所有组件提供回调方法和查 询上下文,它把责任扔给每个组件,让它们使用容器的a p i 来查找资 源和协作者。这种方式的i o c 被限制于容器层,应用程序代码使用容器 提供的回调方法来获取资源。 2 ) 依赖注射:这是轻量型容器使用的方式。组件本身不提供查询操作,而 是提供普通的j a v a 方法,使得容器能够解析出依赖关系。容器从整体 0 四j i i 大学硕士论文 上负责组装组件,把解析的对象传递给j a v a b e a n 属性或构造函数。使 用j a v a b e a n 属性的方法叫做s e t t e ri n j e c t i o n ;使用构造函数的方式叫做 c o n s t r u c t o r 删e c t i o n 。 图2 1 解释了不同类型的i o c 实现方式。 i o c 容嚣管理对象的生命周期 d e p e n d e n c yl o o k u p 当查询上下文可用时容器调用对 象。对象需要实现容器特定的a p i 。 d e p e n d e n c yi n j e c t i o n 在语言层次的依赖关系上组装对 象。没有容器特定的a p i 。 s e t t e ri n j e c t i o n 使用j a v a b e a n 的属性组装对象。 c o n s t r u c t o ri n j e c t i o n 使用构造函数的参数来组装对象。 图2 3 不同类型的i o c 实现方式 2 4 1 1 依赖查询 e j b 和其它的j 2 e ea p i ,如s e r v l e ta p i ,提供了l o c 的依赖查询方式。容 器来管理对象的生命周期,而被管理的对象来负责实现自己的查询。 例如,如果没有使用任何e j b 之外的框架来实现它,你将需要使用j n d i 来查找其它的e j b 和资源。考虑在e j b 层设计使用一个j a v a 类,它由e j b 的 e j b c r e a t e o 方法创建,可以存取j n d i 资源,出于性能和可读性的考虑,你可能 希望缓存这些资源,而不是每次需要的时候都去查找它。因此你可能为这个对 象提供一个构造函数的实现方式: p u b l i cc l a s sm y b u s i n e s s o b j e c ti m p l e m e n t sm y b u s i n e s s i n t e r f a c e p r i v a t ed a t a s o u r c ed s ; p r i v m em y c o l l a b o r a t o rm y c o l l a b o r a t o r ; p r i v a t ei n tm y i n t v a l u e ; 四川大学硕士论文 p u b l i cm y b u s i n e s s o b j e c t ( ) t h r o w sn a m i n g e x c e p t i o n c o n t e x tc t x = n u l l ; t r y c t x = n e wi n i t i a l c o n t e x t o ; d s = ( d a t a s o u r c e ) c t x 1 0 0 k u p ( j a v a :c o m p e n v d a t a s o u r c e n a m e ”) ; m y c o l l a b o r a t o r = ( m y c o l l a b o r a t o r ) c t x 1 0 0 k u p ( j a v a :c o m p e n v m y c o l l a b o r a t o r n a m e ”) ; m y i n t v a l u e = ( ( i n t e g e r ) e t x 1 0 0 k u p ( j a v a :c o m p e n v m y i n t v a l u e n a m e ”) ) i n t v a l u e o ; ) f i n a l l y t r y i f ( c t x ! = n u l l ) c t x c l o s e 0 ; c a t c h ( n a m i n g e x c e p t i o ne x ) l o g g e r w a r n ( “i n i t i a l c o n t e x tt h r e we x c e p t i o no nc l o s e ”,c x ) ; ) ) ) b u s i n e s sm e t h o d s ) 表面上看来,这是一个很好的解决方案。j n d i 从实现的d a t a s o u r c e 和 c o l l a b o r a t o r 中解耦出对象,然后使m y i n t v a l u e 的原始值具体化。我们可以使用 一个不同的数据源或者改变实现m y c o l l a b o r a t o r 接口的类而不用改变j a v a 代码, 因此具有了可拔插性。如果这段代码使用标准的j 2 e ea p i ,它在应用程序服务 器之间也是可移植的。 然而,下面的问题暗示我们可以做的更好: 因为这个类依赖于y n d i ,所以它不能在应用服务器环境之外运行。j n d i 1 2 四川大学硕士论文 对应用服务器的依赖胜于对数据源的依赖。 如果想使用不同于j n d i 的方式查找资源或协作者该怎么办呢? 我们必 须在一个可以覆写的方法或策略接口中重构这段j n d i 代码。总而言之, 外在化m y b u s i n e s s o b j e c t 类的查询策略是有益处的。 这个类很难测试。我们将需要提供一个哑元的j n d i 上下文来做有效的 单元测试。实现你自己的j n d i 是令人厌恶的。 代码太多。不管这个类是否提供商业逻辑,它都必须处理j n d i 。类应 该在一致的抽象级别上包含操作,这个类中低级别的j n d i 代码表现了 一种入侵。虽然通过使用j n d i 库可以隐藏繁琐的细节,比如t r y f i n a l l y 块,但是却不能除去应用程序代码初始化查询的基本责任。 这个类不是强类型的。在所有的情况下我们都需要从o b j e c t 进行类型 转换。当涉及到原始类型,比如i n t 时,这特别令人讨厌,因为这需要 使用相应的对象包装器。 从构造函数中抛出的n a m i n g e x c e p t i o n 将使调用它的代码变的复杂,而 且这种复杂性向外级联。因为对象的初始化操作无法从查询环境失败中 恢复,所以这种失败会引发无法抑制的异常,这是应用程序代码很难捕 捉到的。 即使我们希望测试这个类,也不能脱离容器进行。如果这个类作为e j b 来 实现,我们将不能脱离e j b 容器使用它。 它是一个商业对象,应该负责实现一些商业逻辑,而与处理j n d i 无关。因 此,e j b 从没有打出i o c 的牌予。 当然,在一定时期内依赖查询是必须存在的,因此任何老牌的i o c 容器都 支持它。然而,它具有的某些重要缺陷也意味着,如果可能的话应该避免使用。 2 4 1 1 依赖注射 第二种l o c 实现策略,依赖注射,通常是更可取的。它让容器从整体上负 责依赖查询,在初始化时通过让被管理的对象暴露j a v a b e a n 的s e t t e r 方法或者 构造函数参数来实现在对象之间传递依赖。我把这种方式叫做基于语言的i o c , 因为它没有依靠任何特定的容器a p i 或者接口。 依赖注射配置的基本原则是应用程序对象不负责查找它们依赖的资源或协 四川大学硕士论文 作者。相反,i o c 容器负责配置对象,使资源查找从应用程序代码中分离出来交 由容器执行。 使用依赖注射,i o c 容器实现了垂直开发。容器负责查找资源,给商业对象 提供必须的资源。容器可以在不影响应用程序代码的情况下使用不同的方式重 新配置以便获得资源。 这种方式有下述优点: 彻底地从应用程序代码中删除查询操作。 不再依赖于容器的a p i ,我们只是面对j a v a 语言的概念。因此,在任何 容器外使用应用程序对象都是容易的。 不需要特殊的接口。 依赖注射可以帮助我们最小化应用程序代码对轻量型容器的依赖。实际上, 对大多数对象而言,这是可以彻底除去的。 当然,依赖注射也同样适用于简单的资源,比如s t r i n g 和i n t 。 2 4 1 _ 1 1s e t t e r i n j e c t i o n 使用s e t t e r 埘e c f i o n ,组件通过j a v a b e a n 属性传递对配置值和协作者的依 赖。这建立在j a v a b e a n 惯例之上。一般而言,依赖注射的概念不是特定于j a v a 语言的,其它的语言也支持类似j a v a b e a n 的管理,比如c 群的属性。 下面看一下使用s e t t e rm i e c t i o n 的样例代码: p u b l i cc l a s sm y b u s i n e s s o b j e c ti m p l e m e n t sm y b u s i n e s s i n t e r f a c e p r i v a t ed a t a s o u r c ed s ; p r i v a t em y c o l l a b o r a t o rm y c o l l a b o r a t o r ; p r i v a t ei n tm y i n t v a l u e ; p u b l i cv o i ds e t d a t a s o u r c e ( d a t a s o u r c ed s ) t h i s d s = d s ; p u b l i cv o i ds e t m y c o l l a b o r a t o r ( m y c o l l a b o m t o rm y c o l l a b o r a t o r ) ( t h i s m y c o l l a b o r a t o r = m y c o l l a b o r a t o r ; l 聿 四川大学硕士论文 p u b l i cv o i ds e t m y i n t v a l u e ( i n tm y i n t v a l u e ) t h i s m y i n t v a l u e = m y v a l u e ; ) b u s i n e s sm e t h o d s s e t t e r 方法是在容器初始化对象之后,处理任何商业方法之前被调用。因此, 没有必要担心涉及这些属性的线程问题。 可以看出,资源查找和对j n d i 的依赖已经不见了。相反,使用j a v a b e a n 属性来传递依赖关系。j a v a b e a n 属性也可以用来具体化简单的属性,如i n t 值。 这既可简化代码,又可在更广泛的环境中实现重用。对资源和协作者的依赖仅 仅是为了实现商业逻辑的需要。当容器处理配置时期错误时,也不需要处理 j n d i 异常了。这种方式解决了先前提到的所有限制。 这个类是普通的j a v a 类,不依赖于任何l o c 容器。即使没有任何容器,它 也可以在任何环境下使用。 2 4 1 1 2c o n s t r u c t o ri n j e c t i o n 使用c o n s t r u c t o r 删e c t i o n ,组件通过构造函数参数传递依赖。这种方式的 依赖注射由p i c o c o n t a i n e r 团队在2 0 0 3 年中期发明,现在也被s p r i n g 和 p i c 0 c o n t a i n e r 之外的框架实现了。 下面看一下使用c o n s t r u c t o r 喇e e t i o n 的样例代码: p u b l i cc l a s sm y b u s i n e s s o b j e c ti m p l e m e n t sm y b u s i n e s s i n t e r f a c e p r i v a t ed a t a s o u r c ed s ; p r i v a t em y c o l l a b o r a t o rm y c o l l a b o r a t o r ; p r i v a t ei n tm y i n t v a l u e ; p u b l i cm y b u s i n e s s o b j e c t ( d a t a s o u r c ed s ,m y c o l l a b o r a t o rm y c o l l a b o r a t o r ,i n t m y i n t v a l u e ) t l l i s d s = d s ; t h i s m y c o l l a b o r a t o r = m y c o l l a b o r a t o r ; 四川大学硕士论文 t h i s m y i n t v a l u e = m y v a l u e ; | 嗯u s i n e s sm e t h o d s 这个也是普通的j a v a 类,没有任何i o c 容器特定的代码或者j n d i 。 2 4 1 2 在s e t t e ri n j e c t i o n 和c o n s t r u c t o ri n j e c t i o n 之间的选择 相对于依赖查询而言,s e t t e ri n j e c t i o n 和c o n s t r u c t o ri r i j e e t i o n 两种方式都显 示了巨大的进步。不论使用哪一种,实现依赖注射的基本原理是相同的。那么 在这两者之间应该如何选择呢? s e t t e rt n j e c t i o n 的优势包括: 在i d e 方面,j a v a b e a n 属性得到了很好的支持。 j a v a b e a n 属性可以自我生成文档。 不需要任何代码,j a v a b e a n 属性可以被子类继承。 如果需要的话,标准的j a v a b e a n 属性编辑器也可以用来完成类型转换。 许多现存的j a v a b e a n 可以毫无修改的在面向j a v a b e a n 的l o c 容器中使 用。例如,s p r i n g 用户经常使用j a k a r t ac o m m o n sd b c p 数据源。因为 在s p r i n g 容器中,它们可以通过j a v a b e a n 属性来管理。 如果对应每一个s e t t e r

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论