??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲色四在线视频观看,亚洲风情亚Aⅴ在线发布,亚洲人成电影网站久久http://www.tkk7.com/yesjoy/category/22901.html<font color="red">?lt;/font><font color="blue">d爬山 所以艰?dL 所以苦?lt;/font><font color="red">?lt;/font>zh-cnSun, 05 Sep 2010 02:34:24 GMTSun, 05 Sep 2010 02:34:24 GMT60关于AOP的七个猜?http://www.tkk7.com/yesjoy/articles/120861.html★yesjoy?/dc:creator>★yesjoy?/author>Wed, 30 May 2007 03:41:00 GMThttp://www.tkk7.com/yesjoy/articles/120861.htmlhttp://www.tkk7.com/yesjoy/comments/120861.htmlhttp://www.tkk7.com/yesjoy/articles/120861.html#Feedback0http://www.tkk7.com/yesjoy/comments/commentRss/120861.htmlhttp://www.tkk7.com/yesjoy/services/trackbacks/120861.html1。随处可见猜惟?br>在未来的软g开发过E中QAOP以一U基~程能力的Ş式出玎ͼ与OOP共同发展Q成Z开发环境的一个组成部分。而目前ؓ(f)止,AOP只是作ؓ(f)一U开发工兗或q行时代码而存在。到了那个时候,可能没有哪个产品声称Q?#8220;我用了AOP”Q因为没有哪个品没有用AOPQ就像现在没有哪个品没有用OOP一栗就你的源代码中没有应用到~程语言的AOP能力Q你也可能调用了某个应用了AOP的基库。事实上QAOP之父Kiczales认ؓ(f)AOP可能首先在操作系l上有一定规模的应用?/p>

2。语aU猜惟?/font>
AOP的真正实现是在一个特定的语言基础上的。比如数q之后,人类开始普遍用K语言QK是J的后一个字母)(j)QK语言在语a本n上就可以~织和横切。此时AOP才得到真正的成熟Q因为程序员在编写代码时可能Ҏ(gu)不知道自q到的是曾l的OOq是现在的AOQ只有了解K语言虚拟机构造和背后实现的h才知道。但是,可能׃人固有的思维方式的问题吧QAOP仍然不会(x)比OOP要用的更多Q甚x可能仍然是Kiczales所提到?5% SolutionQ但是,从语a的角度去实现AOP也许?x)给人类的编E观念带来巨大的变化Q这U变化就像OO所带来的一栗?/p>

3。存在AOD/AOA猜想?/font>
OOP对hcȝ影响q不如它的两个弟弟OOA/OODQ后两者已lؓ(f)整个软g开发行业带来了一ơ意义深q的革命Q它臛_使得全世界开发团队的人数扩大?0倍,开发工具和q_的复杂程度增加了10倍,完成客户某些单要求的成本降低?0%Q唯一的遗憄是,软g开发的效率几乎没有数量U上的变化(依据《没有银式V)(j)。既然存在AOPQ我们猜想也?x)存在AOD/AOAQ比如会(x)存在面向斚w的重构手D,面向斚w的设计模式,面向斚w的最?jng)_践,面向斚w的过E管理,以及(qing)在UML的未来版本中看到为面向方向而专门做的改q,甚至d一个新的UML囄型。当q些东西都生的时候,AOP才真正发展到了鼎盛时期?/p>

4。可执行用例猜想?/strong>
AOP是一个广泛适用的充满想象空间的新技术,但是目前Z对AOP的研I方向过于狭H,大部分声U正在研IAOP的开源项目其实是把AOP当成一个辅助工h使用Q这些项目中又有相当一部分是在做企业开发环境下的容器,他们q没有针对AOP本nq行开发。事实上Q依照Jacbson的说法,AOP直接导致Y件的开发分ZUŞ式——对模块的开发和对用例的开发,现在的用例仅仅是囄Q必要转变为OO代码才能执行Q但是一旦有了AOPQAOP可以直接依据用例的定义,多个不同的模块Q可能来自不同的开发单位)(j)q接hQŞ成方面,而方面本w是可以执行的(语言U猜惻I(j)Q所以用例也׃再是囄而是可以执行的了。这对于以UML为核心的C软gq程来说Q是个极好的信号?/p>

5。标准化猜想?/font>
OO的成功经验告诉我们,要想取得最后的胜利Q就要一致对外,l一了内部的概念Q剩下的争论只有实现问题了。我个h认ؓ(f)Q多数OOP语言在概念上都是一致的Q这U概念被语言学称之ؓ(f)语义Q多数OOP的语义来自Smalltalk和C++q些早期试者,数来自Javaq种在技术的成熟期涌现出的商业品。AOP目前q面临着q个问题。业界对AOP的标准化q程有两个猜惻I一是由AspectJ领头Q各大AOP实现都以AspectJ的语义作为研I题的基本用语Q设计和实现沿用现在的思\Q另一个猜x由权威组l,Q开源、商业、或全球研究l织Q,如Eclipse/IBM/OOPSLA{等拿出一个统一的AOP语义内核Q所有AOP目都以该内ؓ(f)基础开发。Java虚拟机是前一U思\的成功案例,后者则以XMLZ表?/p>

6。全静态编l猜惟?/font>
下面讨论一个实际的技术问题。时下多数AOP目采用的编l技术无外乎两种Q静态编l和动态编l。前者是指在~译前(预编译期Q、编译期、和~译后编l,后者是指在q行期编l。Kiczales认ؓ(f)虽然没有明显的技术缺P但动态编l可能会(x)面(f)一些发展远景的问题Q他UC?#8220;软g的演化问?#8221;。不知道我对大师观点的理解是不是准确Q我认ؓ(f)׃被编l的代码是在变化Q发展)(j)中的Q我们L希望q种变化对编l本w的影响最,q时静态编l面临的问题最多就是重新编译,而动态编l可能不?x)那么简单。此外,全静态编l会(x)D另一个优点——这听v来有点奇怪——就是能力较弱,因ؓ(f)全静态编l承了OO语言本n的约束,比如Java的约束和.NET之CLR的约束等{,q对于更规范的用开发利器是大有好处的?#8220;应该对hcd备大规模应用的每一U新工具心钛_?#8221;

7。AOP的诞生之qL(fng)惟?/strong>
Kiczales先生在从事AOP的研I和开发之前也曾接触过其它对OOP的改良研IӞ其中包括反射和元对象技术。事实上Q心qx和的_(d)后两者的变通能力和灉|E度都在前者之上,但是正因为如此,语言学家们认为,q些技术ƈ不能有效的改善OOP的弊端,甚至q有可能引狼入室Q带来新?#8220;gh问题”。后来,当Kiczales发现AOPӞ他明白这才是Z真正需要的Q他认ؓ(f)他们抓住了问题的咽喉。时至今日,AOP的实现技术已l千姿百态,癑֮争鸣了,但是QAOP创立之初的种U想法也在这U百׃艳中渐渐被h们遗忘,现在利用反射、元对象技术以?qing)种U双刃剑式的技术来实现AOP的想法已l像争抢参院席位一样争夺市(jng)场的认可Q这是事物的发展q是理想的倒退QAOP何时才能回归它的本原Q上天ؓ(f)它安排的命运I竟如何Q我们拭目以待?br>
最q,我和我的几个朋友正在l织一批开源斗士们合作~写AOP.NETQ这是一个开源YӞ在博客园上可以看到部分有兌目的消息。但是由于种U原因,我们对一些基本的问题q没有达成共识,本文来自我对AOP的一贯看法,也是我对C֛里很多问题的一个集中性回{吧?/p>

Q{载出处:(x)Brian Sun @ 爬树(wi)的(chng)泡[http://www.tkk7.com/briansun]Q?/p>

]]>
AOP技术研I—?Netq_AOP技术研I?/title><link>http://www.tkk7.com/yesjoy/articles/120859.html</link><dc:creator>★yesjoy?/dc:creator><author>★yesjoy?/author><pubDate>Wed, 30 May 2007 03:39:00 GMT</pubDate><guid>http://www.tkk7.com/yesjoy/articles/120859.html</guid><wfw:comment>http://www.tkk7.com/yesjoy/comments/120859.html</wfw:comment><comments>http://www.tkk7.com/yesjoy/articles/120859.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/yesjoy/comments/commentRss/120859.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/yesjoy/services/trackbacks/120859.html</trackback:ping><description><![CDATA[     摘要: 4.1.Netq_AOP技术概?.Netq_与Javaq_相比Q由于它至今在服务端仍不具备与unixpȝ的兼Ҏ(gu),也不具备cM于Javaq_下J2EEq样的企业容器Q?Netq_在大型的企业U应用上Q常ؓ(f)人所诟病。就目前而言Q?Netq_q没有提供AOP技术的直接实现Q而微软在未来对于.Net的发展战略目标,我们仍未可知。但我相信微软对于目前炙手可热的AOP技术应该不?x)视而不见。也许在...  <a href='http://www.tkk7.com/yesjoy/articles/120859.html'>阅读全文</a><img src ="http://www.tkk7.com/yesjoy/aggbug/120859.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/yesjoy/" target="_blank">★yesjoy?/a> 2007-05-30 11:39 <a href="http://www.tkk7.com/yesjoy/articles/120859.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AOP技术研I——Javaq_AOP技术研I?http://www.tkk7.com/yesjoy/articles/120858.html★yesjoy?/dc:creator>★yesjoy?/author>Wed, 30 May 2007 03:37:00 GMThttp://www.tkk7.com/yesjoy/articles/120858.htmlhttp://www.tkk7.com/yesjoy/comments/120858.htmlhttp://www.tkk7.com/yesjoy/articles/120858.html#Feedback0http://www.tkk7.com/yesjoy/comments/commentRss/120858.htmlhttp://www.tkk7.com/yesjoy/services/trackbacks/120858.html3.1 Javaq_AOP技术概?/p>

3.1.1 AOP技术在Javaq_中的应用

AOP在实验室应用和商业应用上QJavaq_始终走在前面。从最初也是目前最成熟的AOP工具——AspectJQ到目前已经融和在企业容器JBoss中的JBoss AOPQ均建立在Javaq_上?/p>

前面已经描述刎ͼAOP的目的就是将核心x点和横切x点分,实际上这是一U分散关注(seperation of concernsQ的思\。在Javaq_下,如果要开发企业的应用,非J2EE莫属。一个J2EE应用pȝ只有部v在J2EE容器中才能运行,那么Z么要划分为J2EE容器和J2EE应用pȝQ?通过对J2EE容器q行机制的分析,我们发现Q实际上J2EE容器分离了一般应用系l的一些通用功能Q例如事务机制、安全机制以?qing)对象池或线E池{性能优化机制。这些功能机制是每个应用pȝ几乎都需要的Q因此可以从具体应用pȝ中分d来,形成一个通用的框架^収ͼ而且Q这些功能机制的设计开发有一定难度,同时q行的稳定性和快速性都非常重要Q必ȝq长旉调试和运行经验积累而成Q因此,形成了专门的J2EE容器服务器品,如Tomcat JBoss、Websphere、WebLogic{?/p>

从J2EE应用系l和容器分离的策略,我们能够看到AOP的媄(jing)子。J2EE应用pȝq当于AOP技术中的核心关注点Q它的内容主要包括企业系l的商业逻辑Q而J2EE容器则类g横切x点,实现的是通用的功能机制。不q业界在选择J2EE容器Ӟ对于EJBq种重量U容器服务器而言Q虽然欣赏其高效、稳定及(qing)企业U的容器服务Q但对于整个容器的高开销、高成本以及(qing)q于复杂的解x案均深怀戒心。因此,随着J2EE的逐步演化Q?#8220;轻量U容器架?#8221;通过开源社区如Ȁ一般的驱动力,逐渐占据了J2EE技术的强势C。而所?#8220;轻量U容?#8221;与EJB提供的重量架构的区别,在于借助了AOP技术和IoCQInversion of ControlQ反转模式)(j)机制Q降低了代码对于专用接口的依赖性,以简短、轻ѝ专注、可UL的方式实C务对象。事实上Q我们看到的好前景是,如果所有企业服务都可以通过AOP机制提供l普通Java对象Q那么深盔重铠的应用服务器就不再有存在的价g?/p>

正是看到了AOP技术在企业U开发中的巨大潜力,?#8220;轻量U容?#8221;也唤起了攚wEJB容器的呼壎ͼ事实上,最新的 EJB V3.0 标准׃用了轻量U容器模型)(j)Q越来越多的AOP工具在Javaq_下应q而生Q从而Ş成了目前AOP工具癑֮争鸣的局面。其中,应用最为广泛的主要包括AspectJ、Spring AOP和JBoss AOP{?/p>

3.1.2 Javaq_下AOP工具的比?/p>

AOP是一Ҏ(gu)技术,而在Javaq_下实现该技术的工具也非常多。虽然AOP的技术要素从本质上来讲是一致的Q但各种工具的实现方法也各有不同Q本节基于AOP的技术要素,对当前应用较q泛的AspectJ、Spring AOP和JBoss AOPq行比较?/p>

3.1.2.1 AOP实现机制的区?/p>

同样是实现AOPQ且AOP的技术要素完全相同,但各UAOP工具对于AOP实现的底层机制却是不相同的?/p>

AspectJ采用了源代码生成技术来实现AOP。它提供了一套独有的ZJavaq_的AOP语法Q以?qing)专有的AspectJ~译器。编译器在编译具有AspectJ语法的JavaE序Ӟ能够识别诸如aspectQpointcut{特D关键字Q然后利用静态织入的方式Q修攚w要被截取的方法所属类的源代码Q把advice或者introduce的业务逻辑代码注入到正的位置。利用AspectJQ可以将核心x点完全独立出来,然后通过AspectJ语法Q编写符合核心关注点要求的横切关注点代码Q最后通过AspectJ~译器,这两者在后期l合h。采用这U静态织入技术,使得q用了AOP技术的pȝ在运行性能上未受到M损失Q因为它没有利用反射技术或代理技术,而仅仅是E序的静态扩展而已。然而这U源代码生成方式实现的AOP虽然在性能上具备一定的优势Q但它同时会(x)l开发带来一定的问题。例如代码的后期修改?x)给pȝ带来不可估量的媄(jing)响?/p>

Spring AOP是Spring框架中的一部分Q但可以作ؓ(f)一个独立的模块单独存在。Spring AOP实现AOP技术从本质上来Ԍ是利用了JDK提供的动态代理技术。而从实际的实现方式来看,则是利用了IoCQInversion of ControlQ反转模式)(j)机制Q同旉用了AOP联盟QAOP AllianceQ的通用AOP接口。首先,Spring AOP通过xml配置文g配置了pointcutQƈ利用InterceptorQ拦截机Q作定的触发条g。Interceptor是由用户自定义的Q它相当于是AOP中的adviceQ但该Interceptor需要实现AOP联盟的通用AOP接口Q例如org.aopalliance.intercept.MethodInterceptor。最后定义一个Spring AOP ProxyFactory用于加蝲执行AOPlgQƈ利用IoC机制advice注入到接口以?qing)实现类中?/p>

JBoss 4.0提供了AOP框架。与Spring一Pq个框架可与JBoss应用服务器紧密结合,也可以单独运行在自己的应用中。JBoss AOP同样需要Interceptor拦截器来完成Ҏ(gu)法的拦截Q它要求所有的Interceptor都必d现org.jboss.aop.Interceptor接口。在q个接口中最重要的方法就是invoke()。该Ҏ(gu)对元数据直接q行操作Qƈ利用反射的原理去拦截Ҏ(gu)的消息。Interceptor相当于AOP的adviceQ至于pointcutQ则在xml配置文g中配|。可以看出,Spring AOP和JBoss AOP在实C属于动态织入的方式Q它们与AspectJ在实C是E然不同的两种方式?/p>

3.1.2.2 关于“AspectQ方面)(j)”的区?/p>

在对aspect的声明上Q可以用类似Java的代码,注释或xml。考虑一个常用的例子Q对Accountcȝ授权{略Q如果以AOP技术来实现Q运用不同的AOP工具Q它们在斚w声明技术上的差异,是显而易见的?/p>

Aspect 中的斚w声明cM?Java 语言中的cd明,如图3.1 所C?/p>

aop3.1.gif
?.1 AspectJ中的斚w声明

׃ AspectJ ?Java 语言语法和语义的扩展Q所以它提供了自q一套处理方面的关键字。除了包含字D和Ҏ(gu)之外QAspectJ 的方面声明还包含pointcut和advice成员。示例中的pointcut使用了修饰符QmodifierQ和通配W(wildcardQ模式来表达“所有公共方?#8221;。对帐户的访问,?pointcut 参数提供。advice使用q个参数Q而pointcut则用 this(account) 把它l定。这样做的效果,是捕获了正在执行的Ҏ(gu)所隶属的Account对象。否则,advice的主体与Ҏ(gu)的主体相伹{advice可以包含认证代码Q或者就像在q个CZ中一P可以调用其他Ҏ(gu)?/p>

JBoss AOP Z XML 的风格来声明斚wQ如?3.2 所C?/p>

aop3.2.gif
?.2 JBoss AOP的方面声?/p>

?XML 风格中,aspect、pointcut和advice的声明都?XML 形式表示的。advice的实玎ͼ用的是普通的 Java Ҏ(gu)Q由JBoss AOP框架调用。pointcut和pointcut到advice的绑定都在方面中用XML注释声明。JBoss 没有昑ּ地绑?Account 参数Q而是提供了对当前正在执行的对象的反射讉KQ因此需要把cd转换到对应的cd。JBoss AOPq可以通过标签的方式对斚wq行声明。标{֝?#8220;@”字符开始,它的使用有点cM?Net中的Attribute?/p>

Spring AOP同样是基?XML 的风格来声明斚wQ如?.3所C?/p>

aop3.3.gif
?.3 Spring AOP的方面声?/p>

与JBoss AOPcMQSpring的advice实现是带有特D参数的JavaҎ(gu)Q由 Spring 框架调用。XML描述accountBeanQSpring框架通过它访?Account 对象Q包括通知使用的拦截器 advisor ?qing)其匚w模式Q还有应用到模式的向前(beforeQ?通知?/p>

׃Spring AOP利用了IoC机制Q因此比较JBoss AOP而言Q在xml配置文g中提供了更加_的配|。而构建、运行和配置 Spring AOP 斚w的过E则与JBoss AOP基本相同Q不qSpring AOP依赖的是Spring框架方便的、最化的运行时配置Q所以不需要独立的启动器?/p>

3.1.2.3 语言机制的区?/p>

    ׃实现机制和语法风格的不同Q三UAOP工具在语a机制上也有很大的不同Q以下从四个斚w来描qAspectJ、JBossAOP和Spring AOP之间的区别?/p>

Q?Qpointcut匚w和复合:(x)AspectJ?JBoss AOP 提供了类似的cd模式支持。它们都允许{֐斚w的匹配,对于 Java 5 应用E序来说Q这些匹配包括注释和泛型。AspectJ提供了一U简z的引用多个cd的技术(例如 Account+ 表示帐户的所有子cdQ。所有的工具都支持通配W匹配。Spring AOP q提供了Ҏ(gu)则表辑ּ的支持。虽然这看v来可能是一个强大的优势Q但q是要指出其他技术已l选择了放弃正则表辑ּQ好让pointcut读v来不是太难,同时不会(x)存在潜在的损実뀂pointcut复合操作W基本上都是相同的。Spring AOP 不提?#8220;?#8221;操作Q这个操作通常与没有在 Spring AOP q接Ҏ(gu)型的容器QcontainmentQ连接点l合使用?/p>

Q?Qadvice形式QAspectJ 支持比其他技术更多的advice形式Q?JBoss AOP 只支持一Uadvice形式。每U通知形式都可以表达成 around adviceQ所?JBoss 的技术是无限的,而且它确实提供了额外的简单性。不好的一面是它损׃z性。另外,advice去遵守普通的 Java 规则Q就像注释和 XML 风格做的那样Q,在一些情况下Ҏ(gu)出问题,因ؓ(f)q些规则是ؓ(f)Ҏ(gu)设计的。AspectJ 拥有把被通知Ҏ(gu)的异?#8220;软化”的能力,q很有用Q但是不W合Ҏ(gu)异常(g)的标准语义?/p>

Q?Qjoin point上下文:(x)?AspectJ中,通过指定和绑定pointcut参数讉K动态连接点的状态,cM于在 Java 语言中声明方法参数的技术(请参阅图3.1Q。这接点上下文提供了静态类型化的好处。JBoss AOP ?Spring AOP 反射性地讉Kq接点的状态,q消除了在切入点表达式中参数l定的复杂性,代h(hun)是参数静态类型化。Java E序员习(fn)惯了Ҏ(gu)参数静态类型化带来的好处,同时q可以从pointcut参数的静态类型化得到同样的好处。所以,?JBoss AOP 最q的发行版本中,有提供静态类型化?#8220;args”的计划?/p>

Q?Q扩展性:(x)aspect的扩展性支持库斚w的部|Ԍq样可以在日后ؓ(f)特定E序这些库斚w具体化。例如,一个方面库可以提供应用E序监视需要的全部逻辑和基设施。但是,要采用某个特定项目的库,那么库用的pointcut必须扩展成应用程序特定的join point。AspectJ 用抽象方面支持扩展性,抽象斚w包含抽象的pointcut和具体的advice。扩展抽象方面的子方面必d体化pointcut。JBoss AOP 使用了完全不同的技术,没有使用抽象切入Ҏ(gu)制。扩展是通过生成aspect的子cRƈ?XML 中或通过注释定义新的advicel定而实现的。pointcut到advice的显式绑定ؓ(f)JBoss AOP提供了显著优势,从而可以很Ҏ(gu)地把斚w扩展到新pȝQ无需要生成子cR?/p>

3.2 Javaq_下AOPL工具研究

3.2.1 AsepctJ研究

AspectJ作ؓ(f)Java~程语言扩展的AOP工具Q得我们运用AOP技术能够像普通的Java~程那样Q特D之处,仅在于我们需要用AspectJ提供的特D语法。接下来Q我通过一些实例,介绍如何q用AspectJ实现AOP技术?/p>

3.2.1.1 AspectJ语言Ҏ(gu)?/p>

讑֮我们的开发项目中需要应用到日志记录Q根据前面介l的AOP知识Q我们已l能够从q个需求中识别出横切关注点——日志记录。因此,我们需要定义关?#8220;日志记录”的aspectQ?/p>

public aspect AutoLog

    pointcut publicMethods() : execution(public * org.apache.cactus..*(..));
    pointcut logObjectCalls() : execution(* Logger.*(..));
    pointcut loggableCalls() : publicMethods() && ! logObjectCalls(); 

    before() : loggableCalls()
    {
      Logger.entry(thisJoinPoint.getSignature().toString());
    }
    after() : loggableCalls()
    {
      Logger.exit(thisJoinPoint.getSignature().toString());
    }
}

如果仅仅熟?zhn)Java~程Q会(x)发现有很多关键字是Java语言中不曑֌含的Q它们均是AspectJ提供的?/p>

分析上述的代码,首先是aspect的声明,它类gJava中的cd明,定义了一个aspectQAutoLog。在q个斚w中分别包含了pointcut和advice?/p>

pointcut共有三个QpublicMethod、logObjectCalls和loggableCalls。publicMethod选择org.apache.cactus包中的所有公共(publicQ方法的执行。所?#8220;选择”Q就意味着它的join point为其选择的方法。当q些Ҏ(gu)被调用时Q就?x)执行pointcut的advice代码。而在pointcut中,execution 是一个原始的 PointcutQ就?int 是一U原始的 Java cdQ。它选择与括号中定义的方法说明匹配的MҎ(gu)的执行。方法说明允许包含通配W。logObjectCalls的pointcut则选择Logger cM的所有方法的执行。第三个pointcut比较Ҏ(gu)Q它使用&& !合ƈ了前两个 PointcutQ这意味着它选者了除LoggercM的公共方法以外, org.apache.cactus 中所有的公共Ҏ(gu)?/p>

advice在aspect中,被用来完成实际的日志U录。advice有三U,分别为before、after和around。如上述代码中定义的adviceQ?br>before() : loggableCalls()
{
    Logger.entry(thisJoinPoint.getSignature().toString());
}

该advice的定义表C的含义是,如果org.apache.cactus中所有的公共Ҏ(gu)QLoggercȝ公共Ҏ(gu)除外Q被执行Q则在这些方法执行之前,需要先执行该advice定义的逻辑?/p>

3.2.1.2 AspectJ的高U语aҎ(gu)?/p>

在本文第二部分介lAOP技术时Q提C横切技术的分类。其中,静态横切技术能够扩展一个对象的l构。用引入(IntroductionQ,Aspect 可以向类中添加新的方法和变量、声明一个类实现一个接口或检查异常{换ؓ(f)未检查异常(unchecked exceptionQ?/p>

3.2.1.2.1 向现有类d变量和方?/p>

假设(zhn)有一个表C持久存储的数据~存的对象。ؓ(f)了测量数据的“更新E度”Q?zhn)可能军_向该对象d旉戌字段Q以便容易地(g)对象是否与后备存储器同步。由于对象表CZ务数据,Ҏ(gu)AOP的知识,我们应该这U机制性细节从对象中隔R?AspectJQ可以用如下代码中所昄的语法来向现有的cL加时间戳讎ͼ(x)

public aspect Timestamp
{
    private long ValueObject.timestamp;
    public long ValueObject.getTimestamp()
    {
       return timestamp;
    }
    public void ValueObject.timestamp()
    {     
       this.timestamp = System.currentTimeMillis();
    }
}

通过introductionQ我们就非常方便的ؓ(f)ValueObjectcdd了timestamp的变量和相关Ҏ(gu)。除了必限定在哪个cM声明引入的方法和成员变量以外Q声明引入的Ҏ(gu)和成员变量几乎与声明常规cL员相同?/p>

3.2.1.2.2实现多承功?/p>

利用introductionQAspectJ允许向接口和cL加成员,也突破了Java语言只能单承的限制Q允许程序按C++方式那样实现多ѝ如果?zhn)希望上述的aspect Timestamp能够泛化 QgeneralizeQ,以便能够对各U对象重用时间戳C码,可以定义一个称?TimestampedObject 的接口,q用引入(IntroductionQ来相同成员和变量d到接口而不是添加到具体cMQ如下所C?
public interface TimestampedObject
{
    long getTimestamp();
    void timestamp();
}
public aspect Timestamp
{
    private long TimestampedObject.timestamp;
    public long TimestampedObject.getTimestamp()
    {
        return timestamp;
    }
    public void TimestampedObject.timestamp()
    {
        this.timestamp = System.currentTimeMillis();
    }
}

Timestamp斚w׃在TimestampedObject接口中引入(introductionQ了Ҏ(gu)的实玎ͼ使得TimestampedObject接口改变其本质,成ؓ(f)了一个特D的cȝ型。特D之处就在于一个已l承了一个类的类cdQ通过AspectJ的语法,仍然可以再次l承TimestampedObjectQ这间接地实现了类的多l承。而这个特D的AspectJ语法是declare parents语法。declare parents和其它AspectJ cd表达一P可以同时应用于多个类型:(x)
declare parents: ValueObject || BigValueObject implements TimestampedObject;

3.2.1.3 ~译器及(qing)工具支持

    要让aspect能够正常工作Q必daspect加入到它们要修改的代码中厅R这工作由AspectJ提供的ajc~译器完成。ajc ~译器用来编译类?Aspect 代码。ajc 既可以作为编译器也可以作为预~译器操作,生成有效?.class ?.java 文gQ可以在M标准 Java 环境Q添加一个小的运行时 JARQ中~译和运行这些文件?/p>

要?AspectJ q行~译Q将需要显式地指定希望在给定编译中包含的源文gQAspect 和类Q,ajc不象javac那样单地为相兛_入模块搜索类路径。之所以这样做Q是因ؓ(f)标准 Java 应用E序中的每个c都是相对分ȝlg。ؓ(f)了正操作,一个类只要求其直接引用的类的存在。Aspect 表示跨越多个cȝ行ؓ(f)的聚集。因此,需要将 AOP E序作ؓ(f)一个单元来~译Q而不能每ơ编译一个类?/p>

AspectJ 当前版本的一个重要限制是其编译器只能aspect加入到它拥有源代码的代码中。也是_(d)不能使用ajcAdviced到预~译cM。AspectJ 团队认ؓ(f)q个限制只是暂时的,AspectJ |站承诺未来的版本(正式?2.0Q将允许字节码的修改?/p>

AspectJ发行版包含了几种开发工兗这预示着 AspectJ 有好的前景,因ؓ(f)它表明了作者对q一部分的一个重要承诺,?AspectJ 对于开发h员将是友好的。对于面?Aspect 的系l工h持尤光要,因ؓ(f)E序模块可能受到它们所未知的模块所影响?/p>

?AspectJ 一起发布的一个最重要的工h囑Şl构览器,它展CZ Aspect 如何与其它系l组件交互。这个结构浏览器既可以作为流行的 IDE 的插Ӟ也可以作为独立的工具。图3.4昄了先前讨论的日志记录CZ的视图?/p>

aop3.4.jpg
?.4 AspectJ提供?#8220;l构览?#8221;工具

除了l构览器和核心~译器之外,(zhn)还可以?AspectJ |站下蝲一?Aspect 支持的调试器、一个javadoc工具、一个Antd以及(qing)一个Emacs 插g?/p>

3.2.2 JBoss AOP研究

JBoss AOP关于AOP的实CAspectJ是两U完全不同的风格。由于Java利用元数据来存储有关cd、方法、字D늚相关信息Q因此,可以通过Java提供的反功能获得模块相关的元数据,Ҏ(gu)法进行拦截,q将被拦截的Ҏ(gu)与aspect逻辑q行兌?/p>

3.2.2.1 拦截器(InterceptorQ?/p>

在JBoss AOP中,是用拦截器来实现advice的。可以自定义拦截器,拦截Ҏ(gu)调用、构造函数调用以?qing)对字段的访问,但JBoss要求q些自定义的拦截器,必须实现org.jboss.aop.Interceptor接口Q?/p>

public interface Interceptor
{
    public String getName();
    public InvocationResponse invoke(Invocation invocation) throws Throwable;
}

在JBoss AOP中,被拦截的字段、构造器和方法均被{化ؓ(f)通用的invokeҎ(gu)调用。方法的参数接收一个Invocation对象Q而方法的q回倹{字D늚存取以及(qing)构造函数则被填入一个InvocationResponse对象。Invocation对象同时q驱动拦截链。下面我们自定义一个拦截器Q它能够拦截构造函数和Ҏ(gu)的调用,q将跟踪信息打印到控制台上:(x)
import org.jboss.aop.*;
import java.lang.reflect.*;

public class TracingInterceptor implements Interceptor
{
    public String getName()
    {
        return TracingInterceptor;
    }
    public InvocationResponse invoke(Invocation invocation) throws Throwable
    {
        String message = null;
        if (invocation.getType() == InvocationType.METHOD)
        {
            Method method = MethodInvocation.getMethod(invocation);
            message = method: + method.getName();
        }
        else
        {
            if (invocation.getType() == InvocationType.CONSTRUCTOR)
            {
                Constructor c = ConstructorInvocation.getConstructor(invocation);
                message = constructor: + c.toString();
            }
            else
            {
                // 不对字段作处理,太繁琐;
                return invocation.invokeNext();
            }
            System.out.println(Entering + message);
        }
        // l箋。调用真正的Ҏ(gu)或者构造函?br>        InvocationResponse rsp = invocation.invokeNext();
        System.out.println(Leaving + message);
        return rsp;
    }
}

在自定义的TracingInterceptorcMQinvoke()Ҏ(gu)对invocation的类型作判断Q以Ҏ(gu)Ҏ(gu)、构造函数和字段cdQ分别作Z同的操作。而其中,invocation.invokeNext()则表C通过一个拦截链获得下一个invocation?/p>

定义的拦截必dxml文g配置Q其绑定到具体的类。这个定义即为AOP中的切入点pointcut。例如具体的cMؓ(f)BusinessObjectQ则该pointcut在xml中的定义如下Q?br><?xml version=”1.0″ encoding=”UTF-8″>
<aop>
    <interceptor-pointcut class=”BusinessObject”>
        <interceptors>
            <interceptor class=”TracingInterceptor” />
        </interceptors>
    </interceptor-pointcut>
</aop>

上面的pointcutl定TracingInterceptorC个叫做BusinessObject的类。如果要该Interceptorl定到多个类Q还可以利用正则表达式。例如,如果你想l定由JVM载入的类Q类表达式将变ؓ(f) .*。如果你仅仅惌t一个特定的包,那么表达式将是bruce.zhang.mypackge.*?/p>

当JBoss AOP独立q行ӞMW合 META-INF/jboss-aop.xml模式的XML文g被JBoss AOP q行期程序蝲入。如果相关的路径被包含在MJAR或你的CLASSPATH目录中,该XML文g在启动Ӟ由JBoss AOP q行期程序蝲入?/p>

JBoss AOPq提供了qo(h)功能Q可以通过在xml文g中配|过滤的标志Q一些特定的Ҏ(gu)Q包括字D늚讉KQ被qo(h)Q从而不再执行Interceptor的相关逻辑。例如,我们要过滤BusinessObjectcȝ所有get()和set()Ҏ(gu)Q以?qing)main()Ҏ(gu)Q则可以修改上述的xml文gQ?br><?xml version=”1.0″ encoding=”UTF-8″>
<aop>
    <class-metadata group=”tracing” class=” BusinessObject “>
        <method name=”(get.*)|(set.*)”>
            <filter>true</filter>
        </method>
        <method name=”main”>
            <filter>true</filter>
        </method>
    </class-metadata>
</aop>

相应的,Interceptor代码也应作相关的修改Q其能够识别配|文件中的filter属性:(x)
public class TracingInterceptor implements Interceptor
{
    ……//getName()Ҏ(gu)略;
    public InvocationResponse invoke(Invocation invocation) throws Throwable
    {
        String filter=(String)invocation.getMetaData(tracing, filter);
        if (filter != null && filter.equals(true))
            return invocation.invokeNext();
        ……//后面的代码略Q?br>    }
}

3.2.2.2 引入QIntroductionQ?/p>

JBoss AOP同样提供introduction功能Q通过它,可以ؓ(f)现有的类引入W三Ҏ(gu)口或cȝAPI了。例如,我们可以为具体的cdBusinessObject提供Tracing的开养I使得BusinessObject对象能够Ҏ(gu)具体的情冉|开或关闭aspect的Tracing功能。ؓ(f)实现该功能,可以定义一个Tracing接口Q?br>public interface Tracing
{
    void enableTracing();
    void disableTracing();
}

接下来需要定义一个؜合类Q它实现了接口Tracing。当BusinessObjectc被实例化时Q该混合cȝ实例׃(x)被绑定到BusinessObject上。实现方法如下:(x)
import org.jboss.aop.Advised;

public class TracingMixin implements Tracing
{
    Advised advised;

    Public TracingMixin(Object obj)
    {
        this.advised = (Advised)obj;
    }
    public void enableTracing()
    {
        advised._getInstanceAdvisor().getMetaData().addMetaData(”tracing”, “filter”, true);
    }
    public void disableTracing()
    {
        advised._getInstanceAdvisor().getMetaData().addMetaData(”tracing”, “filter”, false);
    }
}

enableTracing()Ҏ(gu)filter属性绑定到对象实例。disableTracing()Ҏ(gu)作同L(fng)事,但是filter属性设|ؓ(f)false?/p>

定义了Tracing接口和实C该接口的混合cdQ就可以在xml文g中定义一个pointcutQ强制BusinessObjectcd现Tracing接口Q?br><?xml version=”1.0″ encoding=”UTF-8″>
<aop>
    <introduction-pointcut class=”BusinessObject”>
        <mixin>
            <interfaces>Tracing</interfaces>
            <class>TracingMixin</class>
            <construction>new TracingMixin(this)</construction>
        </mixin>
    </introduction-pointcut>
</aop>

注意xml文g中的标签Q它代表的含义是当BusinessObject对象被实例化Ӟ执行该标签内的代码。以本例而言Q当创徏BusinessObject对象Ӟ一个TracingMixincȝ实例被创徏。Q何单行的Java代码都可以放到标{中?/p>

通过“引入QintroductionQ?#8221;功能Q在处理BusinessObject对象Ӟ可以视其ؓ(f)Tracing接口cd而进行操作了Q如下的CZQ?/p>

public class BusinessObject
{
    public BusinessObject () {}
    public void helloWorld() { System.out.println(Hello World!); }

    public static void main(String[] args)
    {
        BusinessObject bo = new BusinessObject ();
        Tracing trace = (Tracing)this;
        bo.helloWorld();
       
        System.out.println(”Turn off tracing.”);
        trace.disableTracing();
        bo.helloWorld();
       
        System.out.println(”Turn on tracing.”);
        trace.enableTracing();
        bo.helloWorld();
    }
}

注意如下代码Q?br>Tracing trace = (Tracing)this;

此时this代表的即为BusinessObjectQ从Java代码的角度来看,׃BusinessObjectq没有实现Tracing接口Q因此这行代码所C的昑ּ转换为Tracingcd是不成功的。但通过“引入”功能Q得BusinessObject通过混合c,实现了Tracing接口Q从而得如上的代码能够利执行。隐含的意义是Q我们没有修改BusinessObject的定义,而是通过AOP技术,为BusinessObject扩展实现了第三方提供的接口Tracing?/p>

3.2.3 Spring AOP研究

Spring AOP使用UJava实现Q不需要特别的~译q程Q也不需要控制类装蝲层次。与JBoss AOP相同Q它仍然利用了拦截器完成Ҏ(gu)法的拦截。然而,Spring AOP实现AOP的主要技术却主要来自于AOP联盟Q如拦截器应实现org.aopalliance.intercept.MethodInterceptor 接口Q而所有advice必须实现org.aopalliance.aop.Advice标签接口。此外,Spring实现AOP的目标也不同于其他大部分AOP框架Q它的目标不是提供及(qing)其完善的AOP实现Q而是提供一个和Spring IoC紧密整合的AOP实现Q帮助解决企业应?中的常见问题。因此,Spring AOP的功能通常是和Spring IoC容器联合使用的。AOP Advice是用普通的bean定义语法来定义的QAdvice和pointcut本n由Spring IoC 理。这是一个重要的其他AOP实现的区别?/p>

3.2.3.1 切入点(pointcutQ?/p>

Spring的切入点模型能够使pointcut独立于advicecd被重用。同L(fng)pointcut有可能接受不同的advice。将Pointcut接口分成两个部分有利于重用类和方法的匚w部分Qƈ且组合细_度的操作(如和另一个方法匹配器执行一?#8220;q?#8221;的操作)(j)?/p>

在Spring的切入点中,org.springframework.aop.Pointcut接口是重要的接口Q它用来指定通知到特定的cdҎ(gu)目标。完整的接口定义如下:
public interface Pointcut
{
    ClassFilter getClassFilter();
    MethodMatcher getMethodMatcher();
}

ClassFiltecd也是一个接口,该接口被用来切入点限制C个给定的目标cȝ集合?如果matches()永远q回trueQ所有的目标c都被匚w?br>public interface ClassFilter
{
    boolean matches(Class clazz);
}

MethodMatcher接口通常更加重要。完整的接口定义如下Q?br>public interface MethodMatcher
{
    boolean matches(Method m, Class targetClass);
    boolean matches(Method m, Class targetClass, Object[] args);
    boolean isRuntime();
}

matches(Method, Class) Ҏ(gu)被用来测试这个切入点是否匚w目标cȝl定Ҏ(gu)。这个测试可以在AOP代理创徏的时候执行,避免在所有方法调用时都需要进?试。如?个参数的matches()Ҏ(gu)Ҏ(gu)个方法返回trueQƈ且MethodMatcher的isRuntime()也返回trueQ那?个参数的matches()Ҏ(gu)在每次Ҏ(gu)调用的时候被调用。这使切入点能够在目标advice被执行之前立x看传递给Ҏ(gu)调用的参数。由于大部分MethodMatcher都是静态的Q意味着isRuntime()Ҏ(gu)?x)返回false。此U情况下Q?个参数的matches()Ҏ(gu)永远不会(x)被调用?/p>

Spring AOP提供了几个实用的切入点实玎ͼ其中较ؓ(f)常用的是正则表达式切入点Qorg.springframework.aop.support.RegexpMethodPointcutQ它使用Perl 5的正则表辑ּ的语法。用这个类你可以定义一个模式的列表。如果Q何一个匹配,那个切入点将被计成 true。用法如下:(x)
<bean id=”settersAndAbsquatulatePointcut”
    class=”org.springframework.aop.support.RegexpMethodPointcut”>
    <property name=”patterns”>
        <list>
            <value>.*get.*</value>
            <value>.*absquatulate</value>
        </list>
    </property>
</bean>

不过Q更多情况下是直接用RegexpMethodPointcut一个实用子c:(x) RegexpMethodPointcutAdvisor。它允许我们同时引用一个adviceQ在Spring AOP中,advice可以是拦截器Q也可以是before adviceQthrows advice{?。这q化了bean的装配,因ؓ(f)一个bean可以同时当作pointcut和adviceQ如下所C:(x)
<bean id=”myPointcutAdvisor” class=”org.springframework.aop.support.RegexpMethodPointcutAdvisor”>
    <property name=”advice”>
        <ref local=”MyInterceptor” />
    </property>
    <property name=”patterns”>
        <list>
            <value>.*save.*</value>
            <value>.*do.*</value>
        </list>
    </property>
</bean>

注意配置文g中的myPointcutAdvisorQ在Spring AOP中,一个advisor是一个aspect完整的模块化表示。通过advisorQ可以将pointcut和adviceQ在此处即ؓ(f)MyInterceptorQ绑定v来?/p>

3.2.3.2 通知QadviceQ?/p>

Spring AOP的advice可以跨越多个被advice对象׃nQ或者每个被advice对象有自qadvice。要实现adviceQ最单的做法是定义一个拦截器QInterceptorQ。它采用了AOP联盟QAOP AllianceQ的通用AOP接口Q接口定义ؓ(f)aopalliance.jarQ。要实现adviceQ需要实现aopalliance.jar中定义的MethodInterceptor接口?/p>

例如Q我们定义了一个业务对象接口BusinessObject?qing)其实现cBusinessObjectImplQ该业务对象能够存储数据Q其定义如下Q?br>public interface BusinessObject
{
    public void save();
}
public class BusinessObjectImpl implements BusinessObject
{
    public void save()
    {
         System.out.println(”saving domain object……”);
    }
}

现在需要ؓ(f)业务对象BusinessObject的Save()Ҏ(gu)Q提供Lock机制。根据Spring AOP的实现方式,我们可以定义一个LockInterceptor来实现MethodInterceptor接口Q?br>import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class LockInterceptor implements MethodInterceptor
{
    public Object invoke(MethodInvocation invocation) throws Throwable
    {
        // TODO Auto-generated method stub
        lock();
        Object ret= invocation.proceed();
        unlock();
        return ret;
    }
    private void lock()
    {
        System.out.println(”lock domain object…”);
    }
    private void unlock()
    {
        System.out.println(”unlock domain object…”);
    }
}

为将interceptor与具体的advicel定hQ需要在配置文g中配|beanQ?br><bean id=”MyInterceptor” class=”test.aop.spring.LockInterceptor”/>

3.2.3.3 AOP代理与IoC容器

׃Spring中提供了IoC容器Q例如BeanFactoryQ,因此我们可以通过Ioc机制Q利用ProxyFactoryBean来创建AOP代理。ProxyFactoryBean和其他Spring?FactoryBean实现一P引入一个间接的层次。如果你定义一个名字ؓ(f)foo的ProxyFactoryBeanQ引用foo的对象所看到的不是ProxyFactoryBean实例本nQ而是由实现ProxyFactoryBean的类?getObject()Ҏ(gu)所创徏的对象。这个方法将创徏一个包装了目标对象 的AOP代理?/p>

AOP代理利用的是Java的动态代理技术,通过它就可以加蝲q执行AOPlg。同Ӟq需要通过IoC的方式将advice注入到接口以?qing)其实现cR以前面的业务对象BusinessObjectZQ在xml配置文g中的配置如下Q?br><bean id=”myAOPProxy” class=”org.springframework.aop.framework.ProxyFactoryBean”>
    <property name=”proxyInterfaces”>
       <value>test.aop.spring.BusinessObject</value>
    </property>
    <property name=”target”>
       <ref local=”impl” />
    </property>
    <property name=”interceptorNames”>
       <value>myPointcutAdvisor</value>
    </property>
</bean>
<bean id=”impl” class=”test.aop.spring.BusinessObjectImpl”/>

通过上述对pointcut、advice、advisor和AOP代理的配|,我们可以轻易地在Spring中实现AOPQ例如:(x)
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class App
{
    private BusinessObject bo = null;
    public static void main(String[] args)
    {
        ApplicationContext ctx=new FileSystemXmlApplicationContext(”Bean.xml”);
        bo= (BusinessObject) ctx.getBean(”myAOPProxy”);
        bo.save();
    }
}

首先Q通过AOP代理获得BusinessObject对象。当调用BusinessObject对象的save()Ҏ(gu)Ӟ拦截器LockInterceptorҎ(gu)RegexpMethodPointcutAdvisor配置的pointcut和advice之间的关p,判定该方法的调用为join pointQ从而拦截该Ҏ(gu)调用Qƈ注入advice的执行逻辑Q即lock()和unlock()Q最l实CAOP?/p>

3.2.3.4 引入QintroductionQ?/p>

在Spring AOP中,introduction当作advice来处理。与一般的advice一Pintroduction advice相当于一U特D类型的拦截通知Q需要实现IntroductionAdvisor和IntroductionInterceptor接口Q而IntroductionInterceptor接口l承自MethodInterceptorQ?br>public interface IntroductionInterceptor extends MethodInterceptor
{
    boolean implementsInterface(Class intf);
}

Introduction通知不能被用于Q何pointcutQ因为它只能作用于类层次上,而不是方法。我们可以只用InterceptionIntroductionAdvisor来实现导入通知Q它有下面的Ҏ(gu)Q?br>public interface InterceptionIntroductionAdvisor extends InterceptionAdvisor
{
    ClassFilter getClassFilter();
    IntroductionInterceptor getIntroductionInterceptor();
    Class[] getInterfaces();
}

接下来,我以JBoss AOP一节中的例子来说明introduction在Spring AOP中的应用。我们的目标仍然是ؓ(f)一个已有的业务对象引入W三Ҏ(gu)口TracingQ?br>public interface Tracing
{
    void enableTracing();
    void disableTracing();
    boolean enabled();
}

首先Q我们需要一个做大量转化的IntroductionInterceptor。在q里Q我们?org.springframework.aop.support.DelegatingIntroductionInterceptor 实现cR当然我们可以直接实现IntroductionInterceptor接口Q但是大多数情况?DelegatingIntroductionInterceptor是最合适的?/p>

DelegatingIntroductionInterceptor的设计是introduction委托到真正实现introduction接口的接口,隐藏完成q些工作的拦截器。委托可以用构造方法参数设|到M对象中;默认的委托就是自己(当无参数的构造方法被使用Ӟ(j)。这样在下面的例子里Q委托是DelegatingIntroductionInterceptor的子c?TracingMixin。给定一个委托(默认是自w)(j)?DelegatingIntroductionInterceptor实例L被这个委托(而不是IntroductionInterceptorQ实现的所有接口,q支持它们中M一个导入。子cdTracingMixi也可能调用suppressInterflace(Class intf) Ҏ(gu)来隐藏不应暴露的接口。然而,不管IntroductionInterceptor 准备支持多少接口QIntroductionAdvisor控制哪个接口将被实际暴霌Ӏ一个导入的接口隐藏目标的同一个接口的所有实现?/p>

q样QTracingMixinl承DelegatingIntroductionInterceptorq自己实现接口Tracing。父c自动选择支持introduction的TracingQ所以我们不需要指定它。用q种Ҏ(gu)我们可以导入L数量的接口?br>public class TracingMixin extends DelegatingIntroductionInterceptor implements Tracing
{
    private boolean enabled;
    public void enableTracing ()
    {
        this.enabled = true;
    }

    public void disableTracing ()
    {
        this. enabled = false;
    }

    public boolean enabled()
    {
        return this.enabled;
    }
    public Object invoke(MethodInvocation invocation) throws Throwable
    {      
        return super.invoke(invocation);
    }
}

通常不要需要改写invoke()Ҏ(gu)Q实现DelegatingIntroductionInterceptorp够了Q如果是引入的方法,DelegatingIntroductionInterceptor实现?x)调用委托方法?否则l箋沿着q接点处理?/p>

所需的introduction advisor是很单的。只需保存一个独立的TracingMixin实例Qƈ指定导入的接口,在这里就是Tracing。此ӞTracingMixin没有相关配置Q所以我们简单地使用new来创建它?/p>

public class TracingMixinAdvisor extends DefaultIntroductionAdvisor
{
    public TracingMixinAdvisor() {
        super(new TracingMixin(),Tracing.class);
    }
}

我们可以非常单地使用q个advisor。它不需要Q何配|。(但是Q有一Ҏ(gu)必要的:(x)是不可能在没有IntroductionAdvisor 的情况下使用IntroductionInterceptor。)(j) 和引入一P通常 advisor必须是针Ҏ(gu)个实例的Qƈ且是有状态的。我们会(x)有不同的TracingMixinAdvisor。每个被通知对象Q会(x)有不同的TracingMixin。advisorl成了被通知对象的状态的一部分?/p>

在Spring中,Spring AOP的核心API已经基本E_了。和Spring的其它部分一P AOP框架是模块化的,在保留基设计的同时提供扩展。在Spring 1.1?.2阶段有很多地方可能会(x)有所提高Q但是这些地方也保留了向后兼Ҏ(gu)。它们是Q?/p>

Q一Q性能的提高:(x)AOP代理的创建由工厂通过{略接口处理。因此能够支持额外的AOP 代理cd而不影响用户代码或核心实现?br>Q二Q更兯辑֊的pointcutQSpring目前提供了一个具有表辑֊的切入点接口Q同时添加了更多的切入点实现。Spring正在考虑提供一个简单但h强大表达式语a的实?/p>
转脓(chung)来自Q?a >http://www.cnblogs.com/wayne-ivan/archive/2006/09/07/496904.html

]]>
AOP技术研I——AOP技术基 http://www.tkk7.com/yesjoy/articles/120857.html★yesjoy?/dc:creator>★yesjoy?/author>Wed, 30 May 2007 03:36:00 GMThttp://www.tkk7.com/yesjoy/articles/120857.htmlhttp://www.tkk7.com/yesjoy/comments/120857.htmlhttp://www.tkk7.com/yesjoy/articles/120857.html#Feedback0http://www.tkk7.com/yesjoy/comments/commentRss/120857.htmlhttp://www.tkk7.com/yesjoy/services/trackbacks/120857.html2.1 AOP技术v?/p>

AOP技术的诞生q不晚Q早?990q开始,来自Xerox Palo Alto Research LabQ即PARCQ的研究人员对面向对象思想的局限性进行了分析。他们研I出了一U新的编E思想Q借助q一思想或许可以通过减少代码重复模块从而帮助开发h员提高工作效率。随着研究的逐渐深入QAOP也逐渐发展成一套完整的E序设计思想Q各U应用AOP的技术也应运而生?/p>

AOP技术在Javaq_下是最先得到应用的。就在PARC对于面向斚w~程q行研究的同Ӟ国Northeastern University的博士生Cristina Lopes和其同事也开始了cM的思考。最l,国国防先进技术研I计划vQDefense Advanced Research Projects Agency即DARPAQ注意到了这工作,q提供了U研l费Q鼓励将二者的工作成果l合h。他们通过定义一套Java语言的扩展系l,使开发者可以方便的q行面向斚w的开发,q套扩展pȝ被称为AspectJ。之后,AspectJ?002q被转让lEclipse FoundationQ从而成为在开源社ZAOP技术的先锋Q也是目前最为流行的AOP工具?/p>

AspectWerkz则是ZJava的动态的、轻量AOP框架。AspectWerkz仍然是开源社Z的品,由BEA System提供赞助Q开发者则是BEA的两名员工Jonas Bonér和Alexandre Vasseur。最q版本是AspectWerkz 2.0?005q?月,AspectJ和AspectWerkz达成协议Q同意将二者的成果l合CP取其_֍创徏一个单一的工兗他们合作的W一个发布版本ؓ(f)AspectJ 5Q它扩展了AspectJ语言Q以支持ZAnnotation开发风D又支持cMAspectJ代码风格。AspectJ 5也ؓ(f)Java 5的语aҎ(gu)提供完全的AOP支持?/p>

在Java阵营中,商用软g刉商JBoss在其2004q推出的JBoss 4.0中,引入了AOP框架和组件。在JBoss 4.0中,用户可以在JBoss应用服务器外部单独用JBoss AOPQ该版本为JBoss AOP 1.0Q是?004q?0月发布的。在2005q_(d)JBoss AOP框架又发布了1.3.0版本Q新版本对加载期l入QWeevQ和切点Qpoint cutQ匹配的性能做了很大的优化,使应用程序的启动旉大大~短?/p>

作ؓ(f)d的FrameworkQSpring在开发轻量的J2EEӞ应用是非常广泛的。它通过IoC模式QInversion of ControlQ控制反转模式)(j)来实现AOPQ通常被称为Spring AOP。在2004q_(d)被作为Spring框架的扩展而发布,目前版本已更新到1.1.3。Spring AOP作ؓ(f)一U非늕性的Q轻型的AOP框架Q开发者无需使用预编译器或其他的元标{,在JavaE序中应用AOP。目前,AOP的功能完全集成到了Spring事务理、日志和其他各种Ҏ(gu)的上下文中?/p>

?Net的阵营中QAOP技术的应用q不如Java阵营对AOP的关注?005q?月,微Y发布的Enterprise Library提供?U不同的“应用E序块(application blocksQ?#8221;。有个别专家认ؓ(f)Q这些组件可以被认ؓ(f)是方面。但该观点ƈ未得C致的认同。事实上Q在.Netq_下,推动AOP技术发展的原动力ƈ非微软,而是开源社区。虽?dng)微Y的技术专家们亦然听到了在.Net Framework中增加AOP技术的众呼声Q但作ؓ(f)如此巨大的Y件公司,要让它灵zd转变战略方向Q显然是不太现实的。正因ؓ(f)此,才赐予了开源社区在AOP技术的研究与探索上一个巨大的发展I间?/p>

与Java阵营中的AOP技术不同,目前?Netq_下的各种AOP工具Q基本上q停留在实验室阶Dc(din)但一些在技术上领先且逐渐成熟的AOP产品Q也在开源社Z渐露峥嵘。这其中主要包括Aspect#QAspectDNGQEos AOP{?/p>

Aspect#是基于Castle动态代理技术来实现的。Castle源于Apache Avalon目Q其目的在于实现一个轻量的IoC容器。Aspect#?005q?月被收录为Castle的其中一个子目。它是针对CLIQ?Net和MonoQ实现的AOP框架Q利用了反射、代理等机制。目前的Aspect#版本?.1.1?/p>

AspectDNG目前的版本ؓ(f)0.7Q仍然处于beta版的阶段。它的实现技术是Zrail的静态织入。Rail属于ILU别下的代码l入Q它自定义的一套xml格式的ILML语言Q能够将原有的程序集拆散成ILML格式Q以便于寚w态程序集q行修改和扩展,从而达到静态织入的目的。因为AspectDNG是属于ILU别下的代码l入Q因此在.Netq_下,q不受具体的~程语言限制?/p>

Eos AOP与AspectDNG一P仍然采用静态织入的方式Q但从语法定义上Q它更近gAspectJ关于AOP的实现。它扩展了C#语法Q引入了aspect、introduce、before、after{关键字Qƈ且提供了专用的Eos~译器。Eos目是于2004q?月开始启动,2005q?月推出的0.3.3版本为最新版本,主要的开发h员ؓ(f)Hridesh Rajan和Kevin Sullivan。前者ؓ(f)Virginia大学计算机系的研I生QEos目最初是由Hridesh Rajan提出的;而后者则计算机系的副教授QAssociate ProfessorQ。所以自Eos诞生之初Q就带有厚的学院派特色?/p>

从AOP技术的整体发展来看Q高性能、稳定、可扩展、易用的AOP框架是其势与目标。从上述对各UAOP技术的分析来看QAOP技术无疑是h共同特点的,而各U实现技术就是围l着q些共性深入与延。接下来Q我概要地介绍AOP的本质,以及(qing)它的技术要素?/p>

2.2 AOP技术本?/p>

2.2.1 技术概?/p>

AOPQAspect-Oriented ProgrammingQ面向方面编E)(j)Q可以说是OOPQObject-Oriented ProgramingQ面向对象编E)(j)的补充和完善。OOP引入装、承和多态性等概念来徏立一U对象层ơ结构,用以模拟公共行ؓ(f)的一个集合。当我们需要ؓ(f)分散的对象引入公p为的时候,OOP则显得无能ؓ(f)力。也是_(d)OOP允许你定义从上到下的关系Q但q不适合定义从左到右的关pR例如日志功能。日志代码往往水^地散布在所有对象层ơ中Q而与它所散布到的对象的核心功能毫无关pR对于其他类型的代码Q如安全性、异常处理和透明的持l性也是如此。这U散布在各处的无关的代码被称为横切(cross-cuttingQ代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用?/p>

而AOP技术则恰恰相反Q它利用一U称?#8220;横切”的技术,剖解开装的对象内部,q将那些影响了多个类的公p为封装到一个可重用模块Qƈ其名ؓ(f)“Aspect”Q即斚w。所?#8220;斚w”Q简单地_(d)是那些与业务无关Q却Z务模块所共同调用的逻辑或责d装v来,便于减少pȝ的重复代码,降低模块间的耦合度,q有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系Q如果说“对象”是一个空心的圆柱体,其中装的是对象的属性和行ؓ(f)Q那么面向方面编E的Ҏ(gu)Q就仿佛(jng)一把利刃,这些空心圆׃剖开Q以获得其内部的消息。而剖开的切面,也就是所谓的“斚w”了。然后它又以巧夺天功的妙手将q些剖开的切面复原,不留痕迹?/p>

使用“横切”技术,AOP把Y件系l分Z个部分:(x)核心x点和横切x炏V业务处理的主要程是核心关注点Q与之关pM大的部分是横切关注点。横切关注点的一个特Ҏ(gu)Q他们经常发生在核心x点的多处Q而各处都基本怼。比如权限认证、日志、事务处理。Aop 的作用在于分ȝl中的各U关注点Q将核心x点和横切x点分d来。正如Avanade公司的高U方案构架师Adam Magee所_(d)AOP的核心思想是“应用程序中的商业逻辑同对其提供支持的通用服务q行分离?#8221;

实现AOP的技术,主要分ؓ(f)两大c:(x)一是采用动态代理技术,利用截取消息的方式,对该消息q行装饰Q以取代原有对象行ؓ(f)的执行;二是采用静态织入的方式Q引入特定的语法创徏“斚w”Q从而得编译器可以在编译期间织入有?#8220;斚w”的代码。然而殊途同归,实现AOP的技术特性却是相同的Q分别ؓ(f)Q?/p>

1、join pointQ连接点Q:(x)是程序执行中的一个精执行点Q例如类中的一个方法。它是一个抽象的概念Q在实现AOPӞq不需要去定义一个join point?br>2、point cutQ切入点Q:(x)本质上是一个捕莯接点的结构。在AOP中,可以定义一个point cutQ来捕获相关Ҏ(gu)的调用?br>3、adviceQ通知Q:(x)是point cut的执行代码,是执?#8220;斚w”的具体逻辑?br>4、aspectQ方面)(j)Qpoint cut和advicel合h是aspectQ它cM于OOP中定义的一个类Q但它代表的更多是对象间横向的关pR?br>5、introduceQ引入)(j)Qؓ(f)对象引入附加的方法或属性,从而达C改对象结构的目的。有的AOP工具又将其称为mixin?/p>

上述的技术特性组成了基本的AOP技术,大多数AOP工具均实Cq些技术。它们也可以是研IAOP技术的基本术语?/p>

2.2.2 横切技?/p>

“横切”是AOP的专有名词。它是一U蕴含强大力量的相对单的设计和编E技术,其是用于徏立松散耦合的、可扩展的企业系l时。横切技术可以得AOP在一个给定的~程模型中穿既定的职责部分Q比如日志记录和性能优化Q的操作?/p>

如果不用横切技术,软g开发是怎样的情形呢Q在传统的程序中Q由于横切行为的实现是分散的Q开发h员很隑֯q些行ؓ(f)q行逻辑上的实现或更攏V例如,用于日志记录的代码和主要用于其它职责的代码缠l在一赗根据所解决的问题的复杂E度和作用域的不同,所引v的؜乱可大可。更改一个应用程序的日志记录{略可能涉及(qing)数百ơ编辑——即使可行,q也是个令h头疼的Q务?/p>

在AOP中,我们这些具有公共逻辑的,与其他模块的核心逻辑U缠在一L(fng)行ؓ(f)UCؓ(f)“横切x点(Crosscutting ConcernQ?#8221;Q因为它跨越了给定编E模型中的典型职责界限?/p>

2.2.2.1 横切x?/p>

一个关注点QconcernQ就是一个特定的目的Q一块我们感兴趣的区域,一D|们需要的逻辑行ؓ(f)。从技术的角度来说Q一个典型的软gpȝ包含一些核心的x点和pȝU的x炏VD个例子来_(d)一个信用卡处理pȝ的核心关注点是借贷/存入处理Q而系l的关注点则是日志、事务完整性、授权、安全及(qing)性能问题{,许多x点——即横切x点(crosscutting concernsQ——会(x)在多个模块中出现。如果用现有的~程Ҏ(gu)Q横切关注点?x)横多个模块,l果是ɾpȝ难以设计、理解、实现和演进。AOP能够比上q方法更好地分离pȝx点,从而提供模块化的横切关注点?/p>

例如一个复杂的pȝQ它p多关注点l合实现Q如业务逻辑、性能Q数据存储、日志和调度信息、授权、安全、线E、错误检查等Q还有开发过E中的关注点Q如易懂、易l护、易q查、易扩展{,?.1演示了由不同模块实现的一批关注点l成一个系l?/p>

aop2.1.gif
?.1 把模块作Z批关注点来实?/p>

通过对系l需求和实现的识别,我们可以模块中的这些关注点分ؓ(f)Q核心关注点和横切关注点。对于核心关注点而言Q通常来说Q实现这些关注点的模块是怺独立的,他们分别完成了系l需要的商业逻辑Q这些逻辑与具体的业务需求有兟뀂而对于日志、安全、持久化{关注点而言Q他们却是商业逻辑模块所共同需要的Q这些逻辑分布于核心关注点的各处。在AOP中,诸如q些模块Q都UCؓ(f)横切x炏V应用AOP的横切技术,关键是要实现对x点的识别?/p>

如果整个模块比Mؓ(f)一个圆׃Q那么关注点识别q程可以用三镜法则来Ş容,I越三棱镜的光束Q指需求)(j)Q照到圆柱体各处,获得不同颜色的光束,最后识别出不同的关注点。如?.2所C:(x)

aop2.2.gif
?.2 x点识别:(x)三棱镜法?/p>

上图识别出来的关注点中,Business Logic属于核心x点,它会(x)调用到SecurityQLoggingQPersistence{横切关注点?/p>

public class BusinessLogic
{
    public void SomeOperation()
    {
       //验证安全性;Securtityx点;
       //执行前记录日志;Loggingx点;

       DoSomething();

       //保存逻辑q算后的数据QPersistencex点;
       //执行l束记录日志QLoggingx点;
    }
}

AOP的目的,是要将诸如Logging之类的横切关注点从BusinessLogiccM分离出来。利用AOP技术,可以对相关的横切x点封装,形成单独?#8220;aspect”。这׃证了横切x点的复用。由于BusinessLogiccM不再包含横切x点的逻辑代码Qؓ(f)辑ֈ调用横切x点的目的Q可以利用横切技术,截取BusinessLogiccM相关Ҏ(gu)的消息,例如SomeOperation()Ҏ(gu)Q然后将q些“aspect”l入到该Ҏ(gu)中。例如图2.3Q?/p>

aop2.3.gif
?.3 横切关注点l入到核心关注点?/p>

通过利用AOP技术,改变了整个系l的设计方式。在分析pȝ需求之初,利用AOP的思想Q分d核心x点和横切x炏V在实现了诸如日志、事务管理、权限控制等横切x点的通用逻辑后,开发h员就可以专注于核心关注点Q将_֊投入到解决企业的商业逻辑上来。同Ӟq些装好了的横切关注点提供的功能,可以最大限度地复用于商业逻辑的各个部分,既不需要开发h员作Ҏ(gu)的编码,也不?x)因ZҎ(gu)切关注点的功能而媄(jing)响具体的业务功能?/p>

Z建立松散耦合的、可扩展的企业系l,AOP应用到的横切技术,通常分ؓ(f)两种cdQ动态横切和静态横切?/p>

2.2.2.2 动态横?/p>

动态横切是通过切入点和q接点在一个方面中创徏行ؓ(f)的过E,q接点可以在执行时横向地应用于现有对象。动态横切通常用于帮助向对象层ơ中的各U方法添加日志记录或w䆾认证。在很多应用场景中,动态横切技术基本上代表了AOP?/p>

动态横切技术的核心主要包括join pointQ连接点Q,point cutQ切入点Q,adviceQ通知Q和aspectQ方面)(j)。在前面Q我已经概要Cl了q些术语分别代表的含义。接下来Q我以一个具体的实例来进一步阐q它们在AOP动态横切中实现的意义?/p>

考虑一个电(sh)子商务系l,需要对订单q行d、删除等理操作。毫无疑问,在实际的应用场景中,q些行ؓ(f)应与权限理l合Q只有获得授权的用户方能够实施这些行为。采用传l的设计Ҏ(gu)Q其伪代码如下:(x)
public class OrderManager
{
    private ArrayList m_Orders;
    public OrderManager()
    {
       m_Orders = new ArrayList();
    }
    public void AddOrder(Order order)
    {
        if (permissions.Verify(Permission.ADMIN))
        {

            m_Orders.Add(order);
        }
    }

    public void RemoveOrder(Order order)
    {
        if (permissions.Verify(Permission.ADMIN))
        {
            m_Orders.Remove(order);
        }
    }
}

同样的,在该?sh)子商务pȝ中,q需要对商品q行理Q它采用了同L(fng)授权机制Q?br>public class ProductManager
{
    private ArrayList m_Products;
    public ProductManager()
    {
        m_Products = new ArrayList();
    }
    public void AddProduct(Product product)
    {
        if (permissions.Verify(Permission.ADMIN))
        {
             m_Products.Add(product);
        }
    }
    public void RemoveProduct(Product product)
    {
        if (permissions.Verify(Permission.ADMIN))
        {
             m_Products.Remove(product);
        }
    }
}

如此以来Q在整个?sh)子商务pȝ中,核心业务包括订单理和商品管理,它们都需要相同的权限理Q如?.4所C:(x)

aop2.4.gif
?.4 ?sh)子商务pȝ的权限验证实?/p>

毫无疑问Q利用AOP技术,我们可以分离出系l的核心x点和横切x点,从横向的角度Q截取业务管理行为的内部消息Q以辑ֈl入权限理逻辑的目的。当执行AddOrder(){方法时Q系l将验证用户的权限,调用横切x炚w辑Q因此该Ҏ(gu)即ؓ(f)AOP的join point。对于电(sh)子商务系l而言Q每个需要权限验证的Ҏ(gu)都是一个单独的join point。由于权限验证将在每个方法执行前执行Q所以对于这一pdjoin pointQ只需要定义一个point cut。当pȝ执行到join point处时Q将Ҏ(gu)定义L扑֯应的point cutQ然后执行这个横切关注点需要实现的逻辑Q即advice。而point cut和adviceQ就l合成了一个权限管理aspect?/p>

aop2.5.gif
?.5 AOP动态横切的技术实?/p>

׃aspect是一个封装的对象Q我们可以定义这样一个aspectQ?br>private static aspect AuthorizationAspect{……}

然后在这个aspect中定义point cutQ在point cut中,定义了需要截取上下文消息的方法,例如Q?br>private pointcut authorizationExecution():
execution(public void OrderManager.AddOrder(Order)) ||
execution(public void OrderManager.DeleteOrder(Order)) ||
execution(public void ProductManager.AddProduct(Product)) ||
execution(public void ProductManager.DeleteProduct(Product));

׃权限验证是在订单理Ҏ(gu)执行之前完成Q因此在before advice中,定义权限(g)查:(x)
before(): authorizationExecution()
{
    if !(permissions.Verify(Permission.ADMIN))
    {
        throw new UnauthorizedException();
    }
}

通过定义了这样一个完整的aspectQ当pȝ调用OrderManager或ProductManager的相x法时Q就触发了point cutQ然后调用相应的advice逻辑。如此以来,OrderManager和ProductManager模块׃权限理模块完全解除了依赖关p,同时也消除了传统设计中不可避免的权限判断的重复代码。这对于建立一个松散耦合、可扩展的系lY件是非常有利的?/p>

2.2.2.3 静态横?/p>

静态横切和动态横切的区别在于它不修改一个给定对象的执行行ؓ(f)。相反,它允?dng)R过引入附加的方法字D和属性来修改对象的结构。此外,静态横切可以把扩展和实现附加到对象的基本结构中。在AOP实现中,通常静态横切称为introduce或者mixin?/p>

静态横切在AOP技术中Q受到的x相对较少。事实上Q这一技术蕴含的潜力是巨大的。用静态横切,架构师和设计者能用一U真正面向对象的Ҏ(gu)有效地徏立复杂系l的模型。静态横切允许?zhn)不用创徏很深的层ơ结构,以一U本质上更优雅、更逼真于现实结构的方式Q插入跨整个系l的公共行ؓ(f)。尤其是当开发应用系l时Q如果需要在不修改原有代码的前提下,引入W三方品和API库,则静态横切技术将发挥巨大的作用?/p>

举例来说Q当前已l实C一个邮件收发系l,其中cMail完成了收发邮件的功能。但在品交付后Q发现该pȝ存在~陷Q在收发邮gӞ未曾实现邮g地址的验证功能。现在,W三方品已l提供了验证功能的接口IValidatableQ?br>public interface IValidatable
{
    bool ValidateAddress();
}

我们可以利用设计模式中的Adapter模式Q来完成对第三方产品API的调用。我们可以定义一个新的类MailAdapterQ该cdCIValidatable接口Q同时承了Mailc:(x)
public class MailAdapter:Mail,IValidatable
{
     public bool ValidateAddress()
     {
         if(this.getToAddress() != null)
         {
             return true;
         }
         else
         {
             return false;
         }
     }
}

通过引入MailAdapterc,原来Mail对象完成的操作,全部被MailAdapter对象取代。然而,此种实现方式虽然能解军_入新接口的问题,但类g面的代码Q却是无法编译通过的:(x)
Mail mail = new Mail();
IValidatable validate = ((IValidatable)mail).ValidateAddress();

必须第一行代码作如下修改Q?br>Mail mail = new MailAdapter();

利用AOP的静态横切技术,可以IValidatable接口l入到原有的MailcMQ这是一U非常Ş象的introduce功能Q其实现仍然是在aspect中完成:(x)
import com.acme.validate.Validatable;

public aspect MailValidateAspect
{
    declare parents: Mail implements IValidatable;

    public boolean Mail.validateAddress()
    {
         if(this.getToAddress() != null)
         {
              return true;
         }
         else
         {
              return false;
         }
    }
}

静态横切的Ҏ(gu)Qƈ没有引入cMMailAdapter的新c,而是通过定义的MailValidateAspect斚wQ利用横切技术ؓ(f)Mailcintroduce了新的方法ValidateAddress()Q从而实CMail的扩展。因此如下的代码完全可行?br>Mail mail = new Mail();
IValidatable validate = ((IValidatable)mail).ValidateAddress();

2.3 AOP技术的优势

AOP技术的优势是显而易见的。在面向对象的世界里Qh们提Z各种Ҏ(gu)和设计原则来保障pȝ的可复用性与可扩展性,以期建立一个松散耦合、便于扩展的软gpȝ。例如GOF提出?#8220;设计模式”Qؓ(f)我们提供了设计的典范与准则。设计模式通过最大程度的利用面向对象的特性,诸如利用l承、多态,对责任进行分R对依赖q行倒置Q面向抽象,面向接口Q最l设计出灉|、可扩展、可重用的类库、组Ӟ乃至于整个系l的架构。在设计的过E中Q通过各种模式体现对象的行为、暴露的接口、对象间关系、以?qing)对象分别在不同层次中表现出来的形态。然而鉴于对象封装的Ҏ(gu)性,“设计模式”的触角始l在接口与抽象中大做文章Q而对于对象内部则无能为力?/p>

通过“横切”技术,AOP技术就能深入到对象内部M覆雨Q截取方法之间传递的消息为我所用。由于将核心x点与横切x点完全隔,使得我们能够独立的对“斚w”~程。它允许开发者动态地修改静态的OO模型Q构造出一个能够不断增长以满新增需求的pȝQ就象现实世界中的对象会(x)在其生命周期中不断改变自w,应用E序也可以在发展中拥有新的功能?/p>

设计软gpȝ时应用AOP技术,其优势在于:(x)

Q一Q在定义应用E序Ҏ(gu)U服务(例如日志Q的所有需求的时候。通过识别x点,使得该服务能够被更好的定义,更好的被~写代码Qƈ获得更多的功能。这U方式还能够处理在代码涉?qing)到多个功能的时候所出现的问题,例如改变某一个功能可能会(x)影响到其它的功能Q在AOP中把q样的麻?ch)称之?f)“U结QtanglingQ?#8221;?/p>

Q二Q利用AOP技术对L的方面进行的分析有助于为开发团队指定一位精于该工作的专家。负责这工作的最佳h选将可以有效利用自己的相x能和l验?/p>

Q三Q持久性。标准的面向对象的项目开发中Q不同的开发h员通常?x)?f)某项服务~写相同的代码,例如日志记录。随后他们会(x)在自q实施中分别对日志q行处理以满不同单个对象的需求。而通过创徏一D单独的代码片段QAOP提供了解册一问题的持久简单的Ҏ(gu)Q这一Ҏ(gu)了未来功能的重用性和易维护性:(x)不需要在整个应用E序中一遍遍重新~写日志代码QAOP使得仅仅~写日志斚wQlogging aspectQ成为可能,q且可以在这之上为整个应用程序提供新的功能?/p>

总而言之,AOP技术的优势使得需要编写的代码量大大羃减,节省了时_(d)控制了开发成本。同时也使得开发h员可以集中关注于pȝ的核心商业逻辑。此外,它更利于创徏松散耦合、可复用与可扩展的大型Y件系l?br>
转脓(chung)来自Q?a >http://www.cnblogs.com/wayne-ivan/archive/2006/09/07/496902.html



]]>
AOP技术研I——引a http://www.tkk7.com/yesjoy/articles/120856.html★yesjoy?/dc:creator>★yesjoy?/author>Wed, 30 May 2007 03:35:00 GMThttp://www.tkk7.com/yesjoy/articles/120856.htmlhttp://www.tkk7.com/yesjoy/comments/120856.htmlhttp://www.tkk7.com/yesjoy/articles/120856.html#Feedback0http://www.tkk7.com/yesjoy/comments/commentRss/120856.htmlhttp://www.tkk7.com/yesjoy/services/trackbacks/120856.html1 引言

软g设计因ؓ(f)引入面向对象思想而逐渐变得丰富h?#8220;一切皆为对?#8221;的精义,使得E序世界所要处理的逻辑化,开发者可以用一l对象以?qing)这些对象之间的关系Y件系lŞ象地表示出来。而从对象的定义,q而到模块Q到lg的定义,利用面向对象思想的封装、ѝ多态的思想Q得Y件系l开发可以向搭徏房屋那样Q@序渐q,从砖矛_楼层Q进而到整幢大厦的徏成。应用面向对象思想Q在设计规模更大、逻辑更复杂的pȝӞ开发周期反而能变的更短。自然其中,需要应用到软g工程的开发定义、流E的q程控制Q乃至于质量的缺L(fng)理。但从技术的l节来看Q面向对象设计技术居功至伟。然而,面向对象设计的唯一问题是,它本质是静态的Q封闭的QQ何需求的l微变化都可能对开发进度造成重大影响?/p>

可能解决该问题的Ҏ(gu)是设计模式。GOF面向对象Y件的设计l验作ؓ(f)设计模式U录下来Q它使h们可以更加简单方便地复用成功的设计和体系l构Q帮助开发h员做出有利于pȝ复用的选择。设计模式解决特定的设计问题Q面向对象设计更灵zR优雅,最l复用性更好。然而,设计模式虽然l了我们设计的典范与准则Q通过最大程度的利用面向对象的特性,诸如利用l承、多态,对责任进行分R对依赖q行倒置Q面向抽象,面向接口Q最l设计出灉|、可扩展、可重用的类库、组Ӟ乃至于整个系l的架构。在设计的过E中Q通过各种模式体现了对象的行ؓ(f)Q暴露的接口Q对象间关系Q以?qing)对象分别在不同层次中表现出来的形态。然而鉴于对象封装的Ҏ(gu)性,“设计模式”的触角始l在接口与抽象中大做文章Q而对于对象内部则无能为力?/p>

Aspect-Oriented ProgrammingQ面向方面编E,AOPQ正好可以解册一问题。它允许开发者动态地修改静态的OO模型Q构造出一个能够不断增长以满新增需求的pȝQ就象现实世界中的对象会(x)在其生命周期中不断改变自w,应用E序也可以在发展中拥有新的功能。AOP利用一U称?#8220;横切”的技术,剖解开装的对象内部,q将那些影响了多个类的行为封装到一个可重用模块Qƈ其名ؓ(f)“Aspect”Q即斚w。所?#8220;斚w”Q简单地_(d)是那些与业务无关Q却Z务模块所共同调用的逻辑或责任,例如事务处理、日志管理、权限控制等Q封装v来,便于减少pȝ的重复代码,降低模块间的耦合度,q有利于未来的可操作性和可维护性?/p>

面向斚w~程QAOPQ是施乐公司帕洛阿尔托研I中心(Xerox PARCQ在上世U?0q代发明的一U编E范式。但真正的发展却兴v于近几年对Y件设计方兴未艄研究。由于Y件系l越来越复杂Q大型的企业U应用越来越需要h们将核心业务与公׃务分RAOP技术正是通过~写横切x点的代码Q即“斚w”Q分d通用的服务以形成l一的功能架构。它能够应用程序中的商业逻辑同对其提供支持的通用服务q行分离Q得开发h员从重复解决通用服务的劳动中解脱出来Q而仅专注于企业的核心商业逻辑。因此,AOP技术也受到越来越多的xQ而应用于各种q_下的AOP技术也应运而生。但׃AOP技术相对于成熟的OOP技术而言Q在性能、稳定性、适用性等斚wq有待完善,同时AOP技术也没有形成一个统一的标准,q得AOP技术的研究更具有前沿性的探烦(ch)价倹{?/p> 转脓(chung)来自Q?a >http://www.cnblogs.com/wayne-ivan/archive/2006/09/07/496901.html

]]>
վ֩ģ壺 ƷƬѿ| ҹ1000| ޹ŮaaaëƬ| ߹ۿѸƵ| Ƶۿ| ޺ݺݾþۺһ77777| ھƷ鶹վ91鶹| xxxxձ| ݺady޾Ʒ| պȫƵۿѹۿ| ˳Ƶ߲| ˳վۿ߲| ޾Ʒһ| ձһߵӰ | þֻƷ99| avƬþ| Ʒ޾߹ۿ| 2021պƵ| Ʒվ| ޶ַ㶮| ߲ѲavƬ| ɫ޵һ| ޹ƷߵӰ| ѹ߹ۿ| ߹ۿ| ޳AV߲| ѻɫַ| þùֱ| Ʒһ߹ۿ | ȾþþƷƵ| պƵһ | ޵һҳĻ| ƷƵ| ҹϼӰԺ| ƬAëƬ| þþƷŮav鶹| һëƬ߲| Ƶ߹ۿ| þþƷ| ޾Ʒһ| ղһ|