2005 q? 11 ?
本文的写作源于一个真实的大型软g开发项目,我们努力试在这个项目中推广应用 AOP。在此我们将Ҏl面临过的一些实际问题与困难q行分析Q试囑ּ发关于面向方面Y件开?AOSD)的一些更深层ơ的思考。本文的作者将站在开发? 的角度做出客观的判断Q既不是AOP的狂热鼓吹者,同样也不是AOP反对阵营的一员。因此可以视作来自Java开发者对AOP技术应用的客观分析和徏设? 意见?/blockquote>? 于AOP的概念,W者在q里不再赘述。谁最先创造了AOPQ业界一直有些争议,但普遍接受的说法大概是最先由Gregor J Kiczales在ECOOP'97提出来的Q随后Gregor又申请了AOP的专利[US06467086]。很多h可能不太服气Q因Z们或多或早 已有了类似的xQ只不过没有惛_l他起个新名字Ş了。无论是OOPQMOPQ还是AOPQ其本质的想法都是试囑֜更脓q现实世界的层次上实现Y件开发的 模块化。从q个角度看,AOP的想法不q是新瓶装旧酒Ş了。其实AOP作ؓ新生事物的出玎ͼq不是一U技术上的飞跃,而是软g模块化发展到某一个阶D늚一 个阶D|物。h的思维通常都有一些惯性,在我们饱了OOP的艰辛后Q有一U新的概念蟩出来分析ȝ了OOP的某些缺点,而且以看h合理的方式做出改 q,隑օ会给大家一U耳目一新的感觉。但不可否认的是Q到目前为止QAOP角色所扮演的应用角色更多的只是对OOP的一U补充,因此作ؓ一U重要的 "OP"存在g有些名过其实Q看h更像是一U高U的设计模式。然而,在很多h的眼中AOP的分量甚至不亚于OOPQ甚至AOP被视作未来Y件开发的一 个趋ѝ笔者一直思考一个问题,AOP出现的七八年旉在IT界ƈ不算很短了,有趣的现象是AOP始终保持了小火慢炖的热度Q一直没有像大家所期望的那? 大红大h?/p>
那么AOPI竟在多大程度上可以帮助我们解决实际的问题呢Q让我们试在一个真实的软g开发项目中应用AOP。对AOP所? 崇的各个典型应用方向加以研究Q例如,日志(Log),事务(Transaction), 安全?Security), U程池等{。必说明,我们q里提到的场景,是有一定规模的软g产品开发,我们最l完成的是百兆数量的Y件品,因此我们研究的范围既不是E序员的个h 行ؓQ也不是范围的CZ。让我们一h看一看有什么有的发现?/p>
回页?/b>
我们试验应用AOP的方向很多,q里仅以最具代表性的LogZ。大多数Z解AOPQ都是从l典的Log x点的剥离开始的。因此这是每一个AOP的爱好者都耳熟能详的案例。按道理Q应该是无可争辩的。很不幸Q在我们的研I过E中q是到了很手的问题?/p>
让我们来看一看一个经典的AOP 做日志的例子?/p>
? 们假定,按照AOP的思想Q主逻辑的开发h员在写代码的时候不应该考虑边缘逻辑。因此,上述的日志代码实际对主逻辑的开发者不可见。假定我们以L? Log4J日志的实现方式,以AspectJ作ؓAspect的实现方式。需要重画I本文的写作目的ƈ不是针对某一UAOP的实现^収ͼ选用 AspectJ主要因ؓ从语法的角度而言QAspectJ是目前所有AOP实现中覆盖范围最q的一U实现?/p>
q样一个记日志的横切关注点描述Q是最l典的AOP应用Q它本n是没有Q何问题的。通常我们会怎样用它呢?在承了q个抽象Aspect的子Aspect实现中指定切入点的位|①Qƈ在这个位|上实现的逻辑填入通知(Advice)②?/p>
? 一个小规模的应用开发环境中q样做是不会有问题的Q首先,记日志的切入点不多,无论是采用一对一的位|直接描qͼq是利用l一的编码规范来U束都是可行? ҎQ其ơ,通知中的逻辑不会很复杂。整体的软g开发流E不会有什么变化的需要,通常的做法是׃门的Aspect开发h员统一~写AspectQ而由? 家共享记Log的Aspect。但是不鼓励每一个开发h员都写自qAspectQ这样就不是?cross-cut)Q变成过{子?cross- point)QY件开发变成一盘散沙,失去控制QAOP带来的好处失殆?/p>
那么Q在我们的项目中Q情冉|样呢?上述看似单的两个炚w存在问题Q?/p>
(1) h们统计,在我们开发的软g上一个版本的软g代码中,d?万句记Log的调用。如果我们不做Q何相关的ȝ工作Q直接一对一的对切入点进行描qͼ? 么在位置①上的切入点描述有7万条之多Q姑且不工作量Q即使这样做了,来带来的代码维护将是天文数字的成本Q此路不通?/p>
那么我们只能 寄希望能够提炼出q?万句日志调用的公共模式,我们在这里用到的是一U优化过的LoglgQ接口与LOG4JcMQ考虑到LOG4J的广泛应用,我们下面 以LOG4J为参照。Log LevelcM预定义了五个U别QDEBUG, INFO, WARN, ERRORQFATALQ根据统计,Fatalcd的调用最,ҎFatal的别定义,我们或许可以׃定时间整理代码,提炼出捕捉Fatal点的? 则。然后次之,WARN和ERROR大约?%左右Q这一部分׃好办了,WARN/ERRORcd的LOGq没有严格的界定Q代码的分布点也隑֯规律Q? 一定要扑ֈ规律Q要付出相当大的代h。最后,DEBUG, INFO占据了很大的比例30%-50%Q顾名思义Q这一部分的代码出现的随机性很大,无论怎样努力都不可能扑ֈ有意义的公共规律。此路还是不通?/p>
? 一U说法也许可以解释这U想象:如果切入炚w于描q的时候,很大原因是因为关注点的定义不准确。此说法有一定道理,?日志"作ؓ一个方面来切入_度g 太大了。那么,唯一的办法是?日志"x点进一步拆解。一直拆解到可以接受的程度。但是,我们的问题似乎还没有解决Q如果我们的目_,那么q样? 拆解L有一定的限度的,q种做法或许可行。但很不q,我们的项目很大,要经q相当多的分解才能最l找到日志的规律性。我们还是可能需要成百上千条语句? 指定切入点的位置Q最l的l果很隄护,q样的做法对于一个不断演化中的项目而言是脆׃至于不可接受的。况且,像Debugq样的LogU别Q无Z 怎样拆解Q都不可能找到完的规律。通常QQ何一个系l中的Log都会保持逻辑的一致性,如果l过了这L层层分解QLog作ؓ一个逻辑M的完整性被? 全破坏了。这是一Uؓ了AOP而AOP的做法,非但工作量没有减轻,q带来了无穷的后患?/p>
好了Q只剩最后一招了Qؓ了用AOP, 我们牺牲掉Log的某些特性,预先定义好编码的规则和日志原则,强制推行。当Ӟ如果惌全面覆盖所有的日志点,q样的日志原则只能定得非常粗。从AOP 的角度来Ԍ技术上是可行的Q但_放的日志规则会带来Log的信息量疯长Q对于我们的软g目来说Q还是不可接受,因ؓ日志失去了它的精性,会对pȝ? l护产生较大影响Q而且大量日志信息的增长对pȝ整体q行性能的冲L显而易见的?/p>
(2) 在图1 的第二个要点上我们也同样面问题Q也总图上的例子你可能q看不出来,因ؓ在所有的介绍AOP的文档材料中介绍Log的例子都很简单。但是现实生zM? Log很不留情面。很多时候程序对Log的调用都有其Ҏ的原因,它们的Advice需要分别编写。例如在例子产品中我们经帔R要把一个变量传l?日志" 斚w, 而且Q经常要传入一个局部变量。至现在,所有的AOP实现都还不支持对局部变量的捕捉Q在可见的将来也不会有这U实现。好吧,只好重构代码Q如果您想传 参数Q必要遵守我们预先定义的编码命名规则。但是,q样l编Eh员带来的限制会很大,你很难说服开发h员手捧厚厚的~码规范Q小心翼的写程序?/p>
l合上述两个致命~陷Q我们试图推行Log Aspect的工作已l遇C相当的阻力?/p>
回页?/b>
原本看v来一件简单的事情Q现在变得很复杂了,最初的热情变成了爱恨交l与困惑Q一定是哪里Z问题?/p>
? 大型的Y件开发项目里AOP的切入点应该怎样控制Q这牉|到开发的程Q版本控Ӟ~码规则{等。似乎AOP本nq没有给出明的{复。当我们谈OOP? 时候,涉及到的更多的是c,l承Q多态,而更深层ơ的Ҏ学被隐藏在OOA与OOD中。类似的Q我们在提到AOP的时候,表面上似乎就是AspectQ? pointcutQadviceQ? 然而隐藏在代码后面的面向方面的_֍却被忽略了。因此,我们dQ在我们学习应用AOP的时候,不要q分沉迷于代码,应当合理的在分析、设计上投入更多? _֊。这是我们从上述的失败经历中得到的第一个教训。才能的? 我们不能把AOP惌成ؓ万灵丹,服用之后立刻生效。相反,在实际项目中应用AOP需要多斚w的考虑Q这h可能对由AOP产生的问题胸有成竏V?/p>
? 某种意义上讲Q代码别上的面向方? 无论是面向Java的语a扩展q是XMLQ实现v来ƈ没有太大的不同。但是面向方面的技术也应该体现在不同的抽象层面上,如果在大规模的开发中应用Q? AOA(面向斚w的分?QAOD(面向斚w的分析设?是必不可的Q因此,AOSD(面向斚w的Y件开?更脓切的描述了面向方面实际上是一个完整的 实施q程。关于在更高层面上的AOSDQ很多h正在做有益的试Q例如IBM 支持的基于Eclipse的CME目Q首先要解决的是怎样在Y件开发的初始阶段Q定义合理的x点,至于后面的实现是否基于纯_AOP的工Pq不是重 要的问题。脱d析、设计阶D늚x点分析,直接在代码中使用AOPQ只在小规模的应用中可行Q一旦面向大规模应用Q许多问题就会接t而来?/p>
除此之外Q面向方面的开发过E还必须解决很多的具体问题,诸如Q?/p>
- ? 样在切入点的公共模式与切入点的特征描qC间权衡?q是一个怎样合理的控制AOP的粒度的问题Q前面我们已l提到过Q横切关注点的粒度其实是很难军_的? 在高层次上定义的横切x? 在底层实现的时候还可能会碰到问题。对具体的AOP实现Q可能单U从代码的角度来看,_度划分得越l越单越好。但q样一来,斚w的代码与核心代码׃l? 定很死,不好l护。而且斚w的代码不优雅Q看h好像单纯把一块代码摘出来另放一个地方,L隐藏的痕q很重,很难看出AOP的好处。但_度如果太粗Q? AOP的代码就必须依赖公共模式的ȝQ这L公共模式首先需要花功夫来定义,力求完美Q因则的不断变化会带来很多问题,所以应量避免出现规则的频 J变动。而且Q规则是大家都要遵守的,q样会带来更多的~码限制。当Ӟ对于具体的项目,~码规则的多是具体的问题,但如何能做到适度Qƈ不是一个简? 的问题?/li>
- 很现实的一个问题,如果在大型开发项目有多个横切x点的时候,q些x点之间应该如何打交道。在我们的实际项目中Q就遇到q? 样一个难题,日志x点在很多情况下是与其他横切关注点U缠在一L。其中的N是横切关注点的剥d后顺序问题。在一个版本gl性的开N目中Q由于需 要重构,q个问题更ؓH出。某些情况下Q横切关注点之间如果存在双向的相互依赖,必要修改逻辑Q屏蔽这U可能性,否则Q以目前的AOP的实现方式,? 隑֤理,AOP的代码会很难看,主逻辑的代码重构会UL琐碎Q而且极难l护?/li>
- 在一个大型的软g开发项目中QY件的生命周期应该都处于可 理的状态。如果AOP大规模介入,很多问题都变得很敏感Q尤其是QA。按照AOP的想法,xҎ互相隔离开的,因此Q实质上AOP造成软g模块间的? 合性变得松散了。Y件开发过E的松耦合必然带来试的复杂性。如果系l中的关注点控制在小范围Q那么这U负担可以在范围的开发单位内部消化掉Q但一旦关 注点涉及到全局Q这U变动就会蔓Ӟ带来的测试和QA的额外工作会q速增ѝƈ有可能会冲击到现有的试与QA程?/li>
- 大型软g产品的售 后服务,通常都会在必要的时候触及源代码Q以IBMZQ第三的服务支持h员,在源程序上跟踪U错。很不幸Q这些h必须快学会AOPQ否则他们将? 所适从Q因Z们可能根本不知道整个应用逻辑是怎样~织在一L。Y件的l护与服务的成本可能会因此提高,q依赖特定的工具?/li>
回页?/b>
? 先,q里我们再次AOSDQ而不是单U的AOP。面向方面的发展I间Q应该不仅仅局限于代码层面。究竟面向方面是否会在未来很大程度上影响的Y件开? 模式Q目前的形势q不明了。面向方面的分析与设计,应该寚w向方面技术的未来起到d作用。以现在面向代码层的AOP的用法,坦率地讲Q只是一U小范围? 设计模式Qƈ不值得投入太大的热情。很多热门的松散耦合的开发模型,比如SOAQSCA{等Q看h更现实,更合理,他们都有cM的理念,但具有比面向? 面有更好的柔性?/p>
面向斚w的分析与设计必须能够解决下面的问题:
首先Q面向方面的Ҏ学需要完善:
1Q? 怎样从具体需求中定位横切x点;q样的定义一定不是来自于单的Z名字的原则,例如QLog在所有的软g目中都是横切关注点吗?如果我们软g开发的 对象是类似IBM WebSphere q样的J2EE应用服务器,那么事务 (Transaction)q是横切x点吗Q?/p>
2Q?怎样合理的控制方面的_度Q从设计阶段的横切关注点到实现阶D늚斚wQ怎样qx的过渡?我们l常到的问题是Q在实现阶段Q方面之间仍然有怺依赖性的问题Q怎样才能在分析设计阶D就量避免q些问题Q?/p>
3Q?x点的模型表达方式Q我们通过怎样的标准Ş式来表达x点,x点之间的关系Q以及横切关注点与主逻辑之间的关p?
4Q?q样的横切关注点分析是可以重复、可验证的吗Q有没有可行的通用的方法学来帮助我们得横切关注点的识别与规范成ؓ可控的过E?
? ơ,面向斚w的Y件工E是无法回避的重要问题,通过上面的问题分析,怿大家都已l认识到AOP对现有Y件过E各个阶D늚冲击Q因此有必要去规范适用? AOP的新的Y件开发过E。首先,面向斚w的开发必遵循P代的模式。但现有的Y件工E方法都不以让我们有够的信心在当斚w多到一定的E度Ӟ软g? 开发仍然是可控的。ؓ什么面对以前的OOQ基于组件的方式Q甚x新的SOA的开发,我们都不会如此的不安Q主要是因ؓ在这些模式下Q我们都能够比较? 的看到完整品的雏ŞQ而方面一旦多到某U程度,软g的整体性就不能直观的被感知到。因此,面向斚w对开发流E的冲击是不可避免的。特别是叠代的开发方 式,如何Ҏ个开发@环有效控制也是很有学问的?/p>
最后,面向斚w的开发工h大规模应用AOP的技术保障,现有的开发工具都不能保证面向斚w的Y件开发的效率与完整性。我们需要一U能够更好的集成斚w开发的工具。AJDT能够提供一些帮助,但是q远q不够。一个理想的AOP开发工具应该支持:
1Q?软g产品的完整视图,能够以可视ƈ且Ş象的方式l合横切x点和核心x?/p>
2Q?能将AOP技术集成到pȝ的分析设计阶D?/p>
3Q?Z斚wl合的测试与Debug工具Q能够灵zȝҎ不同的关注点l合q行试和Debug
4Q?更加灉|和方便的x点定义方式,对大多数Java开发者屏蔽复杂的Aspect语法
回页?/b>
? 文通过我们在大规模目中应用AOP的实际经验,ȝ了碰到的问题和取得的q展。通过我们的实践与分析Q我们认为在AOP有较大发展之前,以现在的状态, AOP更适合在小规模软g开发项目中应用。而AOP的更大规模应用不仅需要代码AOP强有力的支持Q更依赖于面向方面的分析设计技术与相应软g工程领域 的进展?/p>
最后,在看C问题之余Q我们也看到了AOP技术仍然处于一个不断发展的阶段。关于AOP的文章不断涌玎ͼAOP工具的功能在不断 加强Q而开发h员对AOP的接受程度也在逐步提高。乐观的看,也许在不久的来QAOPp获得理论和实践上的长步,从而解x文中提到的问题。让? 们拭目以待?
回页?/b>
- AspectJ是目前用最q泛也是功能最强大的AOP代码U别的实现。我们可以从http://www.eclipse.org/aspectj 获得它?/li>
- AJDT是基于Eclipse的AspectJ的集成开发环境,它包含了最新版本的AspectJ。可以从http://www.eclipse.org/ajdt 获得它?/li>
- Http://aosd.net 上有很多AOP相关的资料和论文。另外,您也可以通过q个|站参加每年一ơ的AOSD会议?/li>
- Developerworks上的AOP@Workpd能够帮助我们深入了解AOP的现?/li>
- CME是一个有的工具Q它对AOP在整个Y件工E生命周期中的运用提供了支持。特别有的是它能够帮助开发h员发现和提取Crosscutting Concern。可以从http://www.eclipse.org/cme获得它?/li>
回页?/b>
李珉 高软g工程师,技术经理,IBM 中国软g开发实验室 SOA设计中心 主要研究方向为SOAQESBQ目前领g个技术孵化项目小l工作在AOP与模型驱动开发等方向。你可以通过minli@cn.ibm.com联系?/p>
甘志 高软g工程师,IBM 中国软g开发实验室 SOA设计中心 主要研究方向为AOP、SOA和SecurityQ他q对毛球运动很感兴。他在上交通大学计机pLȝl安全方向博士学位,期间发表了多论文和技术书c。你可以通过ganzhi@cn.ibm.com联系他?/p>
王强 软g工程师,IBM 中国软g开发实验室 SOA设计中心 从事Incubator及SOAQGrid目的工作,对J2EE架构、SOA架构、MDA/MDD以及AOPQ网D等技术有较深入的研究?/p>
郭迎?软g工程师,IBM 中国软g开发实验室 SOA设计中心 有多qJava开发经验,目前主要研究方向为AOP、SOA。你可以通过guoyingc@cn.ibm.com联系?/p>
刘昕?软g工程师,IBM 中国软g开发实验室 SOA设计中心 对J2EE、SOA、MDA/MDD、AOP、语义网{相x术有厚兴趣Qƈ在基于Eclipse的插件开发方面有较深入的l验?
]]>