﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-jinfeng_wang-随笔分类-AOP</title><link>http://www.blogjava.net/jinfeng_wang/category/750.html</link><description>G-G-S,D-D-U!</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 10:00:58 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 10:00:58 GMT</pubDate><ttl>60</ttl><item><title>人员、资源、操作及这三者构成的权限控制</title><link>http://www.blogjava.net/jinfeng_wang/archive/2007/02/14/99819.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Wed, 14 Feb 2007 06:53:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2007/02/14/99819.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/99819.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2007/02/14/99819.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/99819.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/99819.html</trackback:ping><description><![CDATA[Web系统因为是面向Internet/Intranet的，所以其安全性比常规的应用程序系统更难以保证。<br /><br />在谈到其安全性的时候，很多的都是从“网络安全”的角度去看待问题，殊不知，堡垒<br />的内部是最最不安全的。对付“黑客攻击”是系统管理员所要面对的问题，而如何更好的<br />加强堡垒内部自身的安全，是在Web程序的设计中就需要考虑的问题。<br /><br />系统管理员所要面对的网络攻击、操作系统 安全不是我所考虑的问题，如何加强Web系统<br />自身的健康是我所最最关心的事情。 <br /><br />从“构造URL”攻击到“注入SQL文”攻击，都是属于过分信任用户输入，而造成的安全问题。<br />这恰恰应该是由应用程序自身加以重视、解决的问题。<br /><br />基于角色的安全控制已经逐渐的被大家逐渐的接受，每个用户被分配为不同的角色，不同的角色<br />具有不同的操作权限。 但是如何划分角色、用户、操作权限，则是需要认真对待的问题。<br /><br />举例：<br />一个MIS系统中，员工有查询工资的权限，但是某个员工是否具有查询其他员工的权限呢？<br /><br />不能深入的追问问题，详细的分辨清楚系统中到底有多少角色、每个用户所在的角色，是不能完成安全控制的。<br /><br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000"><br /><font color="#0000ff" size="5"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />btw: 以上的问题，大家不妨在自己的类似系统中自己去检查一下，有此问题的占绝大多数吧。<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />看过此文的，愿意回答“是”“否”的，可以留言， 也当作一个调查吧。</font><br /></span></div><br /><br />上面的这个例子，就是一个很成熟的办公系统中存在的问题。使用客户端script脚本，控制了用户的界面操作，殊不知maxthon就可以解除这个限制。此系统中，用户的请求都被整理为URL（get方式提交），虽然URL中的键值含义并不是很明显，但是还是可以尝试着去攻击，获取秘密。<br /><br />认真的核查用户的输入，利用AOP部署，细密的对用户的输入进行核查，是很有必要的事情。<br /><br />某个人、某个资源、某个操作，这三个要素组织在一起则是：某个人对某个资源进行某项操作<br />实际情况下，许多人、许多资源、对每个资源冰存在着多个操作。<br /><br />将人、资源、操作进行划分，可以得到：<br />具体的某一类人，可以对某些资源，进行某些的操作＝》 这就是具体的某项权限限制。<br />    某一类人，则可以归纳为角色。<br />    对某些资源的某些操作，则可以归纳为工作任务。<br />也就是说，整个系统是“某个角色去完成某些工作任务，而具体的一个帐户属于某个角色，某项工作则具体的是指对某个资源进行某个操作”。<br /><br />相对来说，系统中的人员是最容易辨认的，系统中的资源也是可以在系统的功能调查时分清楚的，系统中的操作则是最复杂、最难分清晰，甚至在系统完成时都会变化的。<br /><br />只有分辨清楚了系统中的人、资源、操作，才能辨别清楚系统中的具体的权限限制。<br /><br />“基于角色的安全控制”这样的提法，只提及了人，未能强调将资源、操作进行规类，这是很不充分的一种提法。<br /><br />在Web系统中，系统在设计的过程中，就分清楚资源，分清楚操作，极大缩小每个页面的功能、提高页面功能的原子性，这也是权限控制对系统设计提出的一项要求。<br /><br />前面提及使用AOP进行权限控制，现在简述一下各部件的功能：<br />   业务模块－－完成具体的对某个资源的操作；<br />   前台页面模块－－ 完成整体页面的整合；<br />   安全控制模块－－实现安全控制功能，完成人员、角色、工作的逻辑判断；<br />   AOP配置整合模块－－粘合安全控制模块和业务模块；<br /><br /><br />在于如何去解决，而是如何去发现。隐藏起来的问题更是危险。<br /><br />而如何发现问题，则完全是一个素质、能力的事情，也许这是下一个话题。<br /><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/99819.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2007-02-14 14:53 <a href="http://www.blogjava.net/jinfeng_wang/archive/2007/02/14/99819.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AOSD （Aspect-Oriented Software Development with Use Cases） 随想 </title><link>http://www.blogjava.net/jinfeng_wang/archive/2006/01/25/29182.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Wed, 25 Jan 2006 03:17:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2006/01/25/29182.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/29182.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2006/01/25/29182.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/29182.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/29182.html</trackback:ping><description><![CDATA[<P>这几天在看AOSD，有一些疑惑。<BR>在网上找了些资料：<BR><A href="http://canonical.blogdriver.com/canonical/639784.html">http://canonical.blogdriver.com/canonical/639784.html</A><BR><BR><A href="http://gigix.blogdriver.com/gigix/646694.html">http://gigix.blogdriver.com/gigix/646694.html</A><BR><BR><A href="http://webseminar5.unix105.cn4e.com/webseminar/AOSD.ppt">http://webseminar5.unix105.cn4e.com/webseminar/AOSD.ppt</A><BR><BR><A href="http://sunshineormer.blogdriver.com/sunshineormer/847906.html">http://sunshineormer.blogdriver.com/sunshineormer/847906.html</A><BR><BR><BR>看这个图。<BR><BR><IMG alt="" hspace=0 src="http://blog.csdn.net/images/blog_csdn_net/gigix/118915/o_Usecase.jpg" align=baseline border=0><BR></P>
<P>对应这段话：“Jacobson指出每一个use case是一个功能切片(slice), 并为use case中的概念找到了相应的程序对应物，因而可以在后期通过AOP技术将use case slice织入到系统基础架构中，从而构成一种全程建模技术。use case中的generalization可以对应于对象继承， 包含(include)可以对应于对象组合和调用, 而扩展(entension)就对应于AOP。某些use case具有共性，如常见的CURD(Create,Update,Read, Delete)操作，可以被抽象为参数化的use case, 这可以对应于模板(template)概念。”</P>
<P>结合原书：<BR>如果Reservation里面的Create(),Consume()可以真的分解，Create()和Consume()的没有任何关系的话，为何还要将他们放在Reservation里面呢？就是为了OO，为了要把这两个动作放在一个类里面？</P>
<P>我的意思是，如果真的用例之间可以被切开，解决所说的“Tangling”问题，那为何不在实现的时候 也把他们分开呢，每个用例一个类（类似于面向过程编程）？而不是借助于AOP这样的一个中介（貌似的隔离），最后还是将多个用例之间的代码混杂在一起呢！？既然AOSD把他们放在了一个类里面，那么就说们这两个内容确实存在着“Tangling”问题的，而这个问题是在用例分析阶段就该明确的。既然存在着“Tangling”，那么又怎么有一个“切片”，将他们隔开呢？</P>
<P>AOSD中也发现一些内容（基础结构，即领域模型）是无法在多个用例之间切开的，所以又提出了“公共用例”、“基础用例”来弥补一些其原型的漏洞。 到现在为止，我还没发现AOSD中用例切片、用例模块能够多少真正解决问题的思路。<BR></P>
<P>事实上，如果真的没有关系的用例，显然也可以在OOA/OOD的过程中分开来，而无须这里的AOSD所介绍的这些手段。<BR><BR>当然，对于扩展用例以及非功能性需求，AOSD介绍的内容还是相当不错的。<BR><BR>继续研习中！。。。</P><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/29182.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2006-01-25 11:17 <a href="http://www.blogjava.net/jinfeng_wang/archive/2006/01/25/29182.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>two ebook</title><link>http://www.blogjava.net/jinfeng_wang/archive/2005/05/23/5069.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Mon, 23 May 2005 03:23:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2005/05/23/5069.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/5069.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2005/05/23/5069.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/5069.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/5069.html</trackback:ping><description><![CDATA[<DIV align=left><FONT color=#004fc6 size=3>Aspect Oriented Software Development with Use Cases&nbsp; :&nbsp; <A href="http://www18.fixdown.com/ebook/l-aosd02-2005-03-31.rar">http://www18.fixdown.com/ebook/l-aosd02-2005-03-31.rar<FONT color=#004fc6 size=3><BR><BR><BR></A><FONT color=#000000>Aspect-oriented programming (AOP) is a revolutionary new way to think about software engineering. AOP was introduced to address crosscutting concerns such as security, logging, persistence, debugging, tracing, distribution, performance monitoring, and exception handling in a more effective manner. Unlike conventional development techniques, which scatter the implementation of each concern into multiple classes, aspect-oriented programming localizes them.<BR><BR>Aspect-oriented software development (AOSD) uses this approach to create a better modularity for functional and nonfunctional requirements, platform specifics, and more, allowing you to build more understandable systems that are easier to configure and extend to meet the evolving needs of stakeholders.<BR><BR>In this highly anticipated new book, Ivar Jacobson and Pan-Wei Ng demonstrate how to apply use casesa mature and systematic approach to focusing on stakeholder concernsand aspect-orientation in building robust and extensible systems. Throughout the book, the authors employ a single, real-world example of a hotel management information system to make the described theories and practices concrete and understandable.<BR><BR>The authors show how to identify, design, implement, test, and refactor use-case modules, as well as extend them. They also demonstrate how to design use-case modules with the Unified Modeling Language (UML)emphasizing enhancements made in UML 2.0and how to achieve use-case modularity using aspect technologies, notably AspectJ.<BR><BR>Key topics include<BR><BR>Making the case for use cases and aspects<BR><BR>Capturing and modeling concerns with use cases<BR><BR>Keeping concerns separate with use-case modules<BR><BR>Modeling use-cases slices and aspects using the newest extensions to the UML notation<BR><BR>Applying use cases and aspects in projects<BR><BR>Whatever your level of experience with aspect-oriented programming, Aspect-Oriented Software Development with Use Cases will teach you how to develop better software by embracing the paradigm shift to AOSD.</FONT><BR><BR><BR><BR>Applying&nbsp;UML and Patterns 3rd Edition Oct 2004 : <A href="http://www18.fixdown.com/ebook/l-auap06-2005-04-05.rar">http://www18.fixdown.com/ebook/l-auap06-2005-04-05.rar</A>&nbsp; <BR><BR><FONT color=#000000>Applying UML and Patterns is the world's #1 business and college introduction to "thinking in objects"and using that insight in real-world object-oriented analysis and design. Building on two widely acclaimed previous editions, Craig Larman has updated this book to fully reflect the new UML 2 standard, to help you master the art of object design, and to promote high-impact, iterative, and skillful agile modeling practices.<BR><BR>Developers and students will learn object-oriented analysis and design (OOA/D) through three iterations of two cohesive, start-to-finish case studies. These case studies incrementally introduce key skills, essential OO principles and patterns, UML notation, and best practices. You won't just learn UML diagramsyou'll learn how to apply UML in the context of OO software development.<BR><BR>Drawing on his unsurpassed experience as a mentor and consultant, Larman helps you understand evolutionary requirements and use cases, domain object modeling, responsibility-driven design, essential OO design, layered architectures, "Gang of Four" design patterns, GRASP, iterative methods, an agile approach to the Unified Process (UP), and much more. This edition's extensive improvements include<BR><BR>A stronger focus on helping you master OOA/D through case studies that demonstrate key OO principles and patterns, while also applying the UML<BR><BR>New coverage of UML 2, Agile Modeling, Test-Driven Development, and refactoring<BR><BR>Many new tips on combining iterative and evolutionary development with OOA/D<BR><BR>Updates for easier study, including new learning aids and graphics<BR><BR>New college educator teaching resources<BR><BR>Guidance on applying the UP in a light, agile spirit, complementary with other iterative methods such as XP and Scrum<BR><BR>Techniques for applying the UML to documenting architectures<BR><BR>A new chapter on evolutionary requirements, and much more<BR><BR>Applying UML and Patterns, Third Edition, is a lucid and practical introduction to thinking and designing with objectsand creating systems that are well crafted, robust, and maintainable.</FONT><BR><BR><BR><BR></FONT></B></FONT></DIV><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/5069.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2005-05-23 11:23 <a href="http://www.blogjava.net/jinfeng_wang/archive/2005/05/23/5069.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AOP@Work: AOP and metadata: A perfect match, Part 1 (**zz)</title><link>http://www.blogjava.net/jinfeng_wang/archive/2005/03/13/1991.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Sun, 13 Mar 2005 08:21:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2005/03/13/1991.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/1991.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2005/03/13/1991.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/1991.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/1991.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: http://www-128.ibm.com/developerworks/java/library/j-aopwork3/AOP@Work: AOP and metadata: A perfect match, Part 1Contents:Metadata...&nbsp;&nbsp;<a href='http://www.blogjava.net/jinfeng_wang/archive/2005/03/13/1991.html'>阅读全文</a><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/1991.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2005-03-13 16:21 <a href="http://www.blogjava.net/jinfeng_wang/archive/2005/03/13/1991.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IBM －AOP@Work: AOP 工具比较，第 2 部分（zz） </title><link>http://www.blogjava.net/jinfeng_wang/archive/2005/03/13/1990.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Sun, 13 Mar 2005 08:20:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2005/03/13/1990.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/1990.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2005/03/13/1990.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/1990.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/1990.html</trackback:ping><description><![CDATA[<P>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD><SPAN class=astitle>原文地址：<A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml">http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml</A><BR>英文地址：<A href="http://www-128.ibm.com/developerworks/java/library/j-aopwork2/">http://www-128.ibm.com/developerworks/java/library/j-aopwork2/</A><BR><BR><BR>AOP@Work: </SPAN><SPAN class=atitle>AOP 工具比较，第 2 部分</SPAN></TD>
<TD width=8><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=8 border=0></TD>
<TD align=right width=180><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=180 border=0><BR><NOBR></NOBR></TD>
<TD width=6><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=6 border=0></TD></TR>
<TR vAlign=top>
<TD bgColor=#000000 colSpan=5><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=100 border=0></TD></TR>
<TR vAlign=top>
<TD bgColor=#ffffff colSpan=5><IMG height=8 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=100 border=0></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD width=5><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=5 border=0></TD>
<TD width="100%">
<TABLE cellSpacing=0 cellPadding=0 width=168 align=right border=0>
<TBODY>
<TR>
<TD width=8><IMG height=21 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=5></TD>
<TD width=160>
<TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
<TBODY>
<TR>
<TD width=160 bgColor=#000000 height=1><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD align=middle background=/developerworks/cn/i/bg-gold.gif height=5><B>内容：</B></TD></TR>
<TR>
<TD width=160 bgColor=#666666 height=1><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
<TBODY>
<TR>
<TD><A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#IDAYDCAC">构建方面</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#IDAJGCAC">编织和性能</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#IDAFHCAC">性能考虑</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#IDAIYHAC">IDE 集成</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#features">特性比较</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#IDAZ2HAC">下一步是什么</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#IDAR3HAC">底线 </A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#IDARDIAC">结束语</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR><!--Standard links for every dw-article-->
<TR>
<TD><A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#resources">参考资料 </A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#author1">关于作者</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#rating">对本文的评价</A></TD></TR>
<TR>
<TD><IMG height=10 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
<TBODY>
<TR>
<TD width=160 bgColor=#000000 height=1><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD align=middle background=/developerworks/cn/i/bg-gold.gif height=5><B>相关内容：</B></TD></TR>
<TR>
<TD width=160 bgColor=#666666 height=1><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=1 width=160 border=0>
<TBODY>
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AOP@Work: AOP 工具比较，第 1 部分</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www.ibm.com/developerworks/rational/library/2782.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">A look at aspect-oriented programming</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www.ibm.com/developerworks/java/library/j-ajdt/index.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Aspect-oriented development with Eclipse and AJDT</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
<TBODY>
<TR>
<TD width=160 bgColor=#000000 height=1><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD align=middle background=/developerworks/cn/i/bg-gold.gif height=5><B>订阅:</B></TD></TR>
<TR>
<TD width=160 bgColor=#666666 height=1><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=1 width=160 border=0>
<TBODY>
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/newsletter/index.html">developerWorks 时事通讯</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/subscription/index.shtml">developerWorks 订阅<BR xmlns:fo="http://www.w3.org/1999/XSL/Format">(订阅CD 和下载)</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
<TBODY>
<TR>
<TD width=150 bgColor=#000000 colSpan=2 height=2><IMG height=2 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD width=150 bgColor=#ffffff colSpan=2 height=2><IMG height=2 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><SPAN class=atitle2>开发环境</SPAN><BR>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR vAlign=top align=left>
<TD>
<P>级别: 初级</P></TD></TR></TBODY></TABLE>
<P><A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#author1"><NAME>Mik Kersten</NAME></A> （<A href="mailto:beatmik@cs.ubc.ca">beatmik@cs.ubc.ca</A>） <BR>AOP 工具构建师、咨询顾问, University of British Columbia<BR>2005 年 3 月 </P>
<BLOCKQUOTE><IMG height=38 alt="Column icon" src="http://www-900.ibm.com/developerworks/cn/i/c-j-tinkertoys.gif" width=38 align=left border=0><ABSTRACT-EXTENDED>在这个由两部分构成的 AOP 工具比较的第 2 部分中，面向方面专家 Mik Kersten 将把重点放在工具与开发环境的集成以及构建过程上，包括对 AOP 工具 IDE 特性的逐点比较。为了帮助制定最终决策，在进行总结的时候，作者将介绍这些快速发展的工具近期的发展情况，并提供每种工具优缺点的总结。<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">注意，本文将解释最近宣布的 AspectJ 和 AspectWerkz 项目合并的意义。</I></ABSTRACT-EXTENDED></BLOCKQUOTE>
<P>在这个由两部分构成的 AOP 工具比较的<A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">第 1 部分</A> 中，介绍了 4 种领先的 AOP 工具（AspectJ、AspectWerkz、JBoss AOP、Spring AOP）实现核心 AOP 机制的方式。虽然这些工具已经集中在连接点模型、切入点、通知和类型间声明的思想上，但是每种工具在处理 AOP 语法时，仍有各自明显的优缺点。正如在第 1 部分介绍的，语法的决策不仅影响方面编程时的感觉 —— 繁琐的语法 VS 更加直接、作为代码的切入点 VS 注释、通知保存在相同的源文件中 VS 本地化为 XML 中的方面配置 —— 而且还会对语义带来差异。现在，这一部分将继续探索不同技术的意义，但这次的重点是研究以上决策对 AOP 工具在整体开发过程和开发环境中的集成有什么影响。</P>
<P>本文从深入研究 AspectJ 对 Java™ 语言扩展的发展情况开始，重点查看代码风格在方面构建和静态检查方面的优势和不足。然后讨论每种工具的不同编译方式，并用最新的 AWBench 测评结果说明它们对性能的影响。</P>
<P>在 AOP 工具比较的第 2 部分中，最重要的讨论主题可能是 IDE 支持。本文将对每种工具的 IDE 支持逐个特性地进行比较，并对两个实际的 IDE 插件进行看得见的比较。本文还会介绍每种工具的文档和库支持情况，这两者是选择新技术实现时的重要因素。</P>
<P>文章结尾提供了对这些工具未来发展方向的一些推测，概括了每种工具的核心优势与不足。表 1 总结了整篇文章详细讨论的开发环境集成的一些关键因素。</P>
<P><A name=table1><B>表 1. AOP 工具比较：开发环境集成</B></A><BR><IMG height=168 alt="" src="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/table-build.gif" width=583 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="30%" align=right border=1>
<TBODY>
<TR>
<TD background=/developerworks/cn/i/bg-gold.gif>
<P><A name=sidebar1><B>关于本系列</B></A><BR><I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AOP@Work</I> 系列面对的是那些在面向方面编程上有些基础，并且想扩展或加深了解的开发人员（有关 AOP 的背景，请参阅<A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#resources" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">参考资料</A>）。同 developerWorks 的大多数文章一样，本系列的文章非常实用：读完每篇介绍新技术的文章，都可以立即将该技术投入实用。</P>
<P>本系列文章所选择的每位作者，都在面向方面编程领域内处于领先地位，或者具有这方面的专家水准。许多作者都是本系列文章中介绍的项目和工具的参与者。每篇文章都力图提供一个中立的评述，以确保这里所表达观点的公正性与正确性。</P>
<P>请分别就这些文章的评论或问题与它们的作者联系。要对本系列进行整体评论，可以与连载的负责人 <A href="mailto:ndlesiecki@yahoo.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Nicholas Lesiecki</A> 联系。</P>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">关于本文</B><BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">本文并不想突出某一种工具，而是想用一种批判的、没有偏见的方式突出每种工具的优势与不足。虽然作者是 AspectJ 项目的参与者之一，但是在编写本文的时候，也咨询了其他 AOP 工具项目的领导人，以确保公平地展示所讨论的技术。</P></TD></TR></TBODY></TABLE></P>
<P>如果读者已经读过<A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#part1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">第 1 部分</A>，那么现在可能正想进行开发环境集成。</P>
<P><A name=IDAYDCAC><SPAN class=atitle2>构建方面</SPAN></A><BR>在使用 AOP 工具时，不管是使用工具的 IDE 支持，还是通过 Ant 和命令行进行构建，您会注意到的第一件事是：AOP 工具与构建环境集成得怎么样？在谈到构建环境集成的时候，AOP 工具之间的关键区别在于该工具是否采用了语言扩展。虽然 AspectJ 提供了一种代码风格，这种风格是 Java 语言的一种扩展，但是其他三种技术都采用了普通 Java 语言与基于 XML 和注释的方面语言的组合。从集成的观点来看，AspectJ 对 Java 语言的扩展更有利，因为方面声明拥有与类声明一样简洁的格式和易于编辑的方式。但从负面来看，扩展 Java 语言是个挑战，因为每种解析 Java 源代码的工具都必须扩展，才能理解方面。结果，虽然目前有一套 AspectJ 工具（正如在<A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#features" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">特性比较</A>中讨论的），但这个套件仍不完整。</P>
<P>从构建环境的角度看，这些技术的主要区别是：AspectJ 必须提供自己的编译器，而其他工具可以依靠标准的 Java 编译器。AspectJ 编译器扩展了 Eclipse Java 编译器，可以脱离 Eclipse 在命令行上独立运行，也可以用作 Eclipse 和其他 IDE 的插件。AspectJ 编译器对 “.java” 或 “.aj” 文件中声明的 AspectJ 和 Java 代码进行构建，并生成普通的 Java 字节码。虽然要使用新编译器这点有些不足，但是这么做可以提供切入点的静态检查，而且还会带来很大的益处。</P>
<P><A name=IDAEECAC><SPAN class=atitle3>切入点的静态检查</SPAN></A><BR>在处理类时，Java 程序员对静态检查的依赖很重。这意味着，不用过多考虑方法名称的拼写错误，因为编译器能够立即指出这类错误。如果没有进行静态检查，那么这类错误到了运行的时候才会被捕获。AspectJ 对于所有的方面声明都有完整的静态检查，所以 AspectJ 编译器会立即指出切入点中拼写错误的引用。其他 AOP 工具可以检查方面声明的合格程度，但是，不管是用注释还是用 XML 声明，它们都没有提供切入点的静态检查。对于典型的 Java 开发人员来说，这样做的后果是要投入大量精力查看 XML 值，而且还会在运行时带来大量调试错误。如果切入点中放错一个括号，那么不会显示容易修改的编译错误，只会造成很难阅读和调试的运行时堆栈跟踪。</P>
<P>有了 AspectJ 编译器，方面代码就可以得到 Java 代码从静态检查得到的全部好处。如果没有该编译器，那么在键入切入点表达式时，必须非常小心，而且还要适应通过执行应用程序找出错误，因为切入点的表达式非常复杂，所以这很容易带来问题。</P>
<P>在图 1 中可以看到两种工具处理切入点中括号错误的区别。图的上面显示了 AspectJ 中错误的出现方式，图的下面显示了 AspectWerkz 中错误的出现方式。</P>
<P><A name=figure1><B>图 1. 在 AspectJ 中和在 AspectWerkz 中定位语法错误的比较</B></A><BR><IMG height=479 alt="" src="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/figure-error.gif" width=587 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>AspectJ 的编译器在键入代码的时候就会主动解析方面代码，立即指出括号错误。使用 AspectWerkz，则要到运行时才会检查出这个错误。由此可以看到，在没有切入点静态检查的工具中，这类语法错误需要更多时间调试。但是，更常见、更费时的问题则是因为在切入点中拼写出错误类型名这类的错误造成的。在没有进行静态检查的情况下，AOP 框架无法调用任何通知，因此会悄无声息地失败。指出错误在哪特别费时，尤其在初次接触 AOP 和切入点时。有了静态检查，AspectJ 的编译器会发出警告，指出无法解析的类型名称或签名。正如在后面讨论的那样，在即将发布的工具中，可以期盼获得静态检查支持方面的提高。</P>
<P><A name=IDAZECAC><SPAN class=atitle3>未来构建环境的考虑</SPAN></A><BR>AOP 工具的方面声明的简洁性，应当有助于判断该工具静态检查的优势。例如，Spring AOP 创建通知时要进行大量 XML 的搭配。某种工具要求的手工搭配越多，花在编写和调试这个搭配的时间就会越多，尤其在有许多方面的时候。从积极的方面来看，可以通过自动生成 XML 搭配来解决这个问题。稍后将讨论 JBoss AOP 的 Eclipse 插件，它能够做到这一点。</P>
<P>如果选择了 AspectJ 作为 AOP 工具，那么所有需要使用方面的 Java 项目都必须使用 AspectJ 的编译器。对于某些项目来说，这可能存在问题（例如在集中指定生产构建使用的编译器的情况下）。从积极方面来说，AspectJ 编译器打算替代 Java 编译器。另一个有关的考虑是：每种工具因为添加对方面的支持而带来的编译开销各不相同。下一节将详细讨论这一点。最后，还应当记住 AspectJ 的语言扩展方法要求项目中使用的所有与构建有关的工具都要扩展到 AspectJ。这意味着许多现成的解析 Java 代码的工具无法用于 AspectJ 代码（例如，基准和报告工具，依赖性和风格检查器，以及版本控制使用的 <CODE>diff</CODE> 工具）。</P>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">语言扩展在构建集成上的利弊</B><BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">这一节将从构建集成的角度描绘 AspectJ 的语言扩展方法的一些主要利弊：</P>
<BLOCKQUOTE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><B><CODE>-</CODE></B> 使用普通 Java 源代码的工具必须扩展才能用来处理方面代码。<BR><BR><B><CODE>-</CODE></B> 需要使用不同的编译器。<BR><BR><B><CODE>+</CODE></B> 扩展的 Java 编译器提供了全部方面代码的完整静态检测。<BR><BR><B><CODE>+</CODE></B> 编写和调试切入点变得更加容易。 </BLOCKQUOTE>
<P>虽然语言扩展方法生来就有不足，但是它的一些优点将来也可以应用到注释和 XML 风格上。把这些优点提供给注释风格，正是 AspectJ 和 AspectWerkz 两个团队联合进行 @Aspect 开发工作的主要动机，而且这还表明，如果使用底层的 AOP 编译器，那么静态检查也能用于注释风格。目前，虽然还存在其他研究质量的编译器，但是 AspectJ 编译器是惟一达到商业质量的 AOP 编译器。注意，与采用不同编译器的必要性相关的许多关注点都是工具本身所固有的。在构建时、装入时或运行时修改这些字节码的时候，一些影响编译新字节码的问题也会出现。正如下一节将讨论的，这个<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">编织（weaving）</I> 过程是所有 AOP 工具的基本过程，因为是它支持横切关注点的模块化实现。</P>
<P><A name=IDAJGCAC><SPAN class=atitle2>编织和性能</SPAN></A><BR>正如可以用不同的机制（例如，解释或编译成字节码或对象代码）编译和执行 OOP 程序那样，AOP 工具为构建和执行方面提供了不同的工具。<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">方面编织器（aspect weaver）</I> 提供了按照方面中切入点指定的方式自动调用通知的搭配方式。编织器可以接受源代码或二进制形式 AOP 代码作为输入。方面的编织对于性能和可伸缩性有影响，其中大部分取决于编织发生在应用程序生命周期的哪一部分。方面的编织可以在以下时间发生：</P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI><B>构建时</B> —— 如果 OOP 编译器已经扩展到 AOP，那么方面编织就是标准编译的一部分，否则就是编译后的步骤。<BR><BR>
<LI><B>装入时</B> —— 与方面字节码的编译时编织相同，但是，是在类装入的时候进行编织。<BR><BR>
<LI><B>运行时</B> —— 拦截和基于代理的机制提供了切入点匹配的手段，可以决定什么时候应当调用通知。</LI></UL>
<P>AspectJ 和 AspectWerkz 都支持构建时和装入时编织，但是 AspectJ 更侧重于前者，而 AspectWerkz 更侧重于后者。JBoss AOP 和 Spring AOP 则侧重于在运行时使用动态代理和拦截器调用方面。注意，也能将 Java VM 技术扩展到支持运行时编织，但目前这仍然处在研究阶段。使用运行时拦截框架的关键好处是：它很自然地扩展到了方面的<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">热部署（hot deployment）</I>。这意味着可以在运行时激活或禁用所应用的通知。</P>
<P>热部署是 JBoss AOP 的核心特性，它提供了一个应用服务器管理控制台，可以激活和禁止某些方面。在 Spring AOP 中也有热部署。加入 AspectWerkz 构建和装入时编织模型的类似扩展也支持热部署。在 AspectJ 中，用这种方式激活和禁止方面需要用通知中的 “ if” 测试或用 “if” 切入点进行。有时用术语“动态 AOP”来描述热部署，但是请注意，这个术语可能会造成误导，因为所有的 AOP 工具都支持动态连接点模型。而且 Spring AOP 完全基于代理机制。因此，这种工具很适合粗粒度的横切，但是纯粹基于代理的 AOP 不能用来通知精细的连接点（例如方法调用或字段设置）。另一方面，可以在没有构建时或装入时编织的情况下使用 Spring AOP 的代理，这对于某些应用服务器的部署会非常有用。</P>
<P><A name=IDAFHCAC><SPAN class=atitle3>性能考虑</SPAN></A><BR>在 AOP 和性能的讨论中，需要重点关注的是关于 AOP 实现的性能的争论，它们与若干年前关于对象性能问题的争论类似。一般来说，使用方面的代码执行起来与纯粹面向对象的解决方案类似（这类方案中横切代码散落在整个系统中）。在大多数企业应用程序中，执行时间由远程调用和数据库调用决定，所以通常没有必要担心使用任何一种 AOP 工具时的开销。</P>
<P>也就是说，考虑一下AWBench 最新发布的 AOP 工具基准会很有价值（请参阅<A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#resources" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">参考资料</A>）。要理解这些基准，需要考虑 AOP 工具进行方面编织和编译的不同技术对性能的影响方式。</P>
<P>AspectJ 在编译时会带来开销，主要是内存和时间的使用，因为它是在编译时执行大部分通知。在大型项目中，这些开销有可能是很可观的，而且可能带来一些问题，特别是面向方面编程的横切特性通常意味着，在切入点发生变化时，大部分系统都需要重新编译。但它也意味着在运行的时候，几乎不需要为了匹配切入点做额外的工作。另外一个运行时的性能优势来自 AspectJ 和 AspectWerkz 中连接点参数的静态类型检查。这会带来性能飞跃，因为不需要以反射的形式访问连接点上下文了。对比之下，JBoss AOP 和 Spring AOP 基于拦截的技术在运行时有更多的工作要做。因此，在 AWBench 基准评定中可以看到一个趋势：AspectJ 的通知调用最快，然后是 AspectWerkz、JBoss AOP，最后是 Spring AOP。通过比较，AspectJ 的构建时开销最多，AspectWerkz 次之，JBoss AOP 再次，Spring AOP 没有构建时开销。</P>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">拦截的性能利弊</B><BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">JBoss AOP 和 Spring AOP 使用的拦截和基于代理的 AOP 实现主要的性能利弊是什么？</P>
<BLOCKQUOTE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><B><CODE>+</CODE></B> 构建时间的内存和时间开销可以忽略不计。<BR><BR><B><CODE>-</CODE></B> 运行时的通知调用开销，需要决定切入点匹配。 </BLOCKQUOTE>
<P>与任何性能度量标准一样，只能把这些准则当作参考，应当结合应用程序和使用情况来考虑这些准则。例如，与 Spring AOP 一起使用的典型粗粒度方面一般不会产生显著的开销。这里介绍的工具没有任何一个有让人无法接受的硬伤。与以前的一些 AspectJ 和 AspectWerkz 相比，这两种工具进行了更多的优化，其他工具正在紧紧追赶。AOP 编译器相对来说也是一种新发明，目前从研究社区到诸如 AspectJ 之类的实现的优化速度也在加快。当发生这些改进的时候，正如我们期望看到的那样，构建时间会在不断地改进。</P>
<P><A name=IDAIYHAC><SPAN class=atitle2>IDE 集成</SPAN></A><BR>IDE 集成的目标是在熟悉的 IDE 中方便地编写和构建面向方面的程序。要达到这个目标，必须能够在 IDE 中调用 AOP 编译器或编织器。IDE 支持的另外一个主要职责是让系统的横切结构易于导航和理解。</P>
<P>在编辑切入点时，不得不运行系统才能查看结果，寻找受影响的连接点是非常耗时的。与此类似的问题是，开发人员在初次学习 AOP 时经常会问：“<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">怎样才能知道方面在系统上的效果呢？如果其他人签入的方面会影响正在处理的方面又会怎样呢？</I>”通过指出什么时候连接点受通知影响，AOP 工具回答了这些问题。这意味着在处理某个方法的时候，可以看到影响该方法的所有通知。反过来，在编写方面的时候，可以立即看到这个方面影响了哪个连接点。可以想像一下现代 Java IDE 是怎样提供方便的导航方式的，可以从一个方法导航到所有重写它的方法。这种面向对象工具支持使得系统的继承结构清晰可见。而 AOP IDE 支持使得横切结构的效果清晰可见，从而使处理某些方面就像处理对象一样容易。</P>
<P><A name=IDASYHAC><SPAN class=atitle3>插件比较</SPAN></A><BR>每种工具都提供了不同程度的 IDE 支持，在帮助项目选择合适工具的时候，这点可能很重要。研究实际使用 AspectJ 和 JBoss AOP IDE 插件可以让人对它支持的特性范围有个概念。下一节将进一步研究工具的 IDE 插件。</P>
<P>图 2 演示了用于 Eclipse 的 AspectJ 开发工具（AJDT）如何在编辑器中呈现出横切结构，以及如何呈现为了显示方面声明及其效果而扩展的视图。关于这些特性的详细描述以及更多截屏，请参阅<A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#resources" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">参考资料</A>中的 AJDT 文章。</P>
<P><A name=figure2><B>图 2. 用于 Eclipse 的 AspectJ 开发工具（AJDT）插件 V1.2.0</B></A><BR><IMG height=386 alt="" src="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/figure-aspectj-ide-600.gif" width=600 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>下面将重点介绍一些 AJDT 插件的特性；列表编号与图中的标签对应：</P>
<OL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI>包浏览器显示了一些方面和方面声明。切入点和声明出现时有它们自己的图标，这些图标指出了通知的<I>种类</I>（例如：before、after 等）。<BR><BR>
<LI>编辑器支持显示了结构化的注释，允许从某个方面导航到被通知成员。内容辅助弹出对话框则显示了通知体中所有可以使用的连接点上下文。<BR><BR>
<LI>文档大纲（Document Outline）表示活动编辑器的横切结构，代表影响对应连接点的通知和类型间声明。方面成形器（Aspect Visualiser）（在大纲下面，在这个压缩的截屏中勉强可以见到）显示了整个包中或项目中横切的整体效果，并突出了受通知影响的源代码行。<BR><BR>
<LI>受通知影响的方法显示了可以用来导航到相应方面声明的引导注释。所有其他受影响的连接点都显示了相同的结构（例如，受类型间声明影响的类型，以及受通知影响的调用站点。）</LI></OL>
<P>像 AJDT 插件一样，JBoss AOP 插件也支持用视图在横切结构中导航。在图 3 中可以看到，Eclipse 的 JBoss AOP 插件提供了一些与 AJDT 插件相同的功能。它还有两个显著的额外特性：方面管理器视图，用于查看切入点绑定；还有一个 GUI，用于创建基于枚举的切入点。<A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#table2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">表 2</A> 提供了这些插件特性的完整比较。</P>
<P><A name=figure3><B>图 3. JBoss Eclipse 插件 V1.0.1</B></A><BR><IMG height=384 alt="" src="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/figure-jboss-ide-600.gif" width=600 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>下面将重点介绍一些 JBoss AOP 插件的特性；列表编号与图 3 中的标签对应：</P>
<OL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI>在包浏览器中，通知显得和普通 Java 成员一样。<BR><BR>
<LI>方面管理器是 jboss-aop.xml 文件的图形化显示，可以减少由于缺乏静态检查而带来的问题（例如手工编辑 XML 的需要）。它还对程序的横切结构提供了方便的完整系统显示。<BR><BR>
<LI>Java 元素上的一个附加上下文菜单允许直接选取它们，将它们放入一个切入点中，无需编辑切入点表达式。</LI></OL>
<P><A name=features><SPAN class=atitle2>特性比较</SPAN></A><BR>表 2 总结了 4 种工具 IDE 特性当前的情况。它还提供了每种工具现有的库和文档情况的总结。然后是详细讨论。</P>
<P><A name=table2><B>表 2. IDE 支持、库和文档</B></A><BR><IMG height=250 alt="" src="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/table-tools.gif" width=581 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>下面的说明介绍了每种工具的 IDE 支持的关键特性：</P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI><B>AspectJ</B> —— AspectJ 主要的 IDE 支持是针对 Eclipse 的。Oracle JDeveloper、Borland JBuilder 和 Sun NetBeans 插件也提供了不同程度的 AspectJ 支持。但是，目前 JBuilder 和 NetBeans 版本的开发不是很活跃，因此大大落后于 AspectJ 语言的发行进度。随 AspectJ 提供的一个重要工具是 <CODE>ajdoc</CODE>，它可以为 AspectJ 程序生成 Javadoc 风格的文档。对于<A href="http://www-900.ibm.com/developerWorks/cn/java/j-aopwork2/index.shtml#figure3">图 3</A> 中看到的文档大纲中导航的横切结构，<CODE>ajdoc</CODE> 支持用 HTML 文档中的链接对这些结构进行导航。编辑器中的内容助手是一项新特性，对编写方面很有帮助，对那些对语言和各种原生切入点还不太熟悉的人也特别有用。<BR><BR>
<LI><B>AspectWerkz</B> —— AspectWerkz 提供了初级的 Eclipse 插件。插件的成熟度落后于核心 AspectWerkz 实现的成熟度，至于真正的 IDE 支持，不要指望从 AspectWerkz 中可以得到（虽然这是联合 @AspectJ 时预期获得的一个好处）。<BR><BR>
<LI><B>JBoss AOP</B> —— JBoss AOP 也侧重于 Eclipse 支持。JBoss 的 AOP 插件提供了方面管理器，它方便了 XML 配置文件的编辑。Advised Members 视图使得导航横切成为可能。JBoss 还有一个新的动态方面部署 UI，它为 JBoss AOP 提供了在运行时修改应用通知的方便。请注意，JBoss 的 AOP 插件是最近才发布的。它的成熟度还比不上 JBoss AOP 框架的其余部分。<BR><BR>
<LI><B>Spring AOP</B> —— 在编译 XML 文件中的方面规范说明书时，Spring 的 Eclipse 插件会很有帮助，但它没有提供任何特定于 AOP 的功能。</LI></UL>
<P>所有的工具都依赖现有的 Java 调试器进行启动和调试。在所有的工具中，包括那些没有成熟 IDE 支持的工具（AspectWerkz 和 Spring AOP），方面程序的调试都工作得不错。这意味着在通知中和单步执行（single stepping）中设置断点与在普通 Java 类中是一样的。</P>
<P><A name=IDAI2HAC><SPAN class=atitle3>有可能错过的特性</SPAN></A><BR>目前，所有的 IDE 插件中都还缺乏对重构的支持。所以，如果方法名改变，那么本来应当仍然匹配这个方法的切入点可能不再匹配。这是语言扩展不擅长的领域之一。在 AspectJ 不得不为重命名提供自己的重构支持的时候，在某种程度上，其他技术可以利用现有的重构支持。因为基于注释和 XML 风格的工具必须把完全限定 Java 切入点当作字符串，所以它们也可以借助重构工具，重新命名内嵌在 XML 文件和注释中的完全限定 Java 引用。</P>
<P>支持在 IDE 中使用 UML 视图的工具越来越多，尽管对这类视图的应用目前仍然存在争议。目前，还没有与 AspectJ 或其他 AOP 工具兼容的 UML 查看器。如果对 AspectJ 程序使用 UML 查看器，查看器可能会崩溃，因为它要求的是普通 Java 代码。相比之下，普通的 Java 技术会把方面作为普通的 Java 类显示。这样做的好处是有限的，因为它无法显示在通知与受影响的连接点之间，或者通知与通过类型间声明添加的附加成员之间的所有有意义的关系。</P>
<P><A name=IDAP2HAC><SPAN class=atitle3>文档和库</SPAN></A><BR>除了 IDE 支持，工具的文档和库支持也是评估的重要因素。每种工具都提供了在线文档，但是 Spring 框架为其 AOP 功能提供的是有点分散的、以实现为中心的文档。<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">无需 EJB 的 J2EE</I> 和其他关于 Spring 框架的书籍会很快填补这个空白。AspectJ 是 AOP 工具的最好证明，目前有六本这方面的书正在印刷。注意，可使用文档的状态仅仅反映了每个项目已经进行的时间长短。</P>
<P>Spring AOP 提供了优秀的库支持。与 Spring 框架的集成意味着它利用了依赖注入的（dependency-injecting）方面，提供了复杂成熟的事务拦截器库，而且支持一些有趣的第三方方面（例如 Acegi 安全性框架）。Spring 的 AOP 库拥有在应用服务器之间移植的优点，而且精心挑选的框架组件方式使它很容易接纳模块中其他利用 AOP 支持的部分。JBoss AOP 提供了与 JBoss 框架和 JEMS 堆栈的其他部分的良好集成，而且拥有目前能够得到的最丰富的方面库。这些库包括对 JBoss Cache、J2EE 按需使用、JBoss remoting、异步方面和 JMX 方面的支持。目前，虽然已经用这些工具创建了一些第三方库，但 AspectJ 和 AspectWerkz 不包括任何库。未来的发行版承诺将提供库支持。</P>
<P><A name=IDAZ2HAC><SPAN class=atitle2>下一步是什么</SPAN></A><BR>评估 AOP 工具时要考虑的最后一个因素就是它们的下一步是什么。所有这些工具都在快速走向成熟，目前的实现工作正在解决这里讨论的许多问题。更有趣的是某些技术的优势正在渗透到其他技术中。例如，横切视图曾经是 AspectJ 所特有的，但现在 JBoss AOP 也提供了横切视图，而且很快其他工具也会提供。合并后的 @AspectJ 会把 AspectJ 工具支持的许多优点带到 AspectWerkz 的注释风格中。@AspectJ 还提供了语言扩展风格与注释风格之间的互操作性，这样，语言的语法也将成为开发人员的一个选择。</P>
<P>沿着这条路，对 AOP 重构的研究将会提供所有技术都能使用的结果。用于图形选择和切入点操作的 UI 将从一些常见的直观推断中受益，这些直观推断能够将选择和搜索结果转换成切入点。UML 视图也会开始显示 AOP 声明和联合。全面支持这些新特性是有可能的，这要感谢一些领先的 AOP 工具在语义上的汇集。</P>
<P>长远来看，性能应该是一个不是问题的问题。就像开发人员不该担心虚拟方法分派的开销一样，他们也不用担心通知的调用开销。目前在很大程度上这是事实，而且随着编织器的改进，以及与 JIT 和 VM 的集成越来越紧密，情况还会变得更好。</P>
<P>还有另外两个趋势正在出现，但是还不确定。首先，AOP 的连接点模型和切入点机制的适用性超越了编程语言，对于能够从描述运行时事件的简洁语言中受益的其他工具来说，AOP 的连接点模型和切入点机制也很适用。随着越来越多的人采用 AOP 工具，切入点的应用在调试器、profiler 这类工具中的应用可能越来越普遍。例如，可以在特定的控制流程中设置断点。另一个正在出现的趋势与模型驱动的开发（model-driven development MDD）有关。由于横切的问题在系统中是如此基本的一个问题，所以 MDD 工具会从模型化的横切结构以及生成的方面中获益。</P>
<P>以下是期望从这些工具即将发布版本中得到的一些具体特性的列表：</P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI><B>AspectJ 和 AspectWerkz</B> —— AspectJ 5 会提供对切入点泛型的支持特性。@AspectJ 语法会支持 AspectWerkz 注释风格。<BR><BR>
<LI><B>JBoss AOP</B> —— 参数的静态类型化、性能提高、库和更多的 IDE 支持特性。<BR><BR>
<LI><B>Spring AOP</B> —— 性能提高、与 AspectJ 切入点的互操作性，以及把某些 Spring AOP 服务打包成 AspectJ 方面。</LI></UL>
<P><A name=IDAR3HAC><SPAN class=atitle2>底线 </SPAN></A><BR>如果存在这里给出的优势和不足，如何判断为特定项目选择哪个工具？在采用某项技术时可能遇到的主要问题是什么？这里是每种工具的强项与弱点的一个概括，可以帮助您制定最终决策。下面将开始介绍手工编写横切问题与使用 AOP 工具进行处理的优劣对比。</P>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">所有工具 VS 手工编码的横切</B></P>
<BLOCKQUOTE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><B><CODE>-</CODE></B> 目前还不支持高级 IDE 特性（例如重构）。<BR><BR><B><CODE>+</CODE></B> 一些方面天生就处于复杂系统中，如果没有 AOP 工具，实现会变得非常脆弱，难以发展。<BR><BR><B><CODE>+</CODE></B> 横切变得很明确，易于推理和修改。<BR><BR></BLOCKQUOTE>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AspectJ</B></P>
<BLOCKQUOTE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><B><CODE>-</CODE></B> 语言扩展要求使用已扩展的编译器和相关工具。<BR><BR><B><CODE>-</CODE></B> 缺少库。<BR><BR><B><CODE>+</CODE></B> 简洁的方面声明和切入点的静态检查。<BR><BR><B><CODE>+</CODE></B> 成熟的 IDE 集成。<BR><BR><B><CODE>+</CODE></B> 丰富的文档。<BR><BR></BLOCKQUOTE>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AspectWerkz</B></P>
<BLOCKQUOTE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><B><CODE>-</CODE></B> 不太简洁的方面和切入点声明。<BR><BR><B><CODE>-</CODE></B> 缺少切入点的静态检查。<BR><BR><B><CODE>-</CODE></B> 缺少库。<BR><BR><B><CODE>+</CODE></B> 与 AspectJ 类似的机制，没有语言扩展。<BR><BR><B><CODE>+</CODE></B> 支持方面的热部署。<BR><BR></BLOCKQUOTE>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">JBoss AOP</B></P>
<BLOCKQUOTE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><B><CODE>-</CODE></B> 缺少切入点的静态检查。<BR><BR><B><CODE>-</CODE></B> 缺少到其他应用服务器的移植性。<BR><BR><B><CODE>+</CODE></B> 有丰富的企业方面库集合可用，与丰富的 JBoss 和 JEMS 库集成在一起。<BR><BR><B><CODE>+</CODE></B> IDE 支持降低了采用难度，减少了手工编写 XML 代码的需要。<BR><BR><B><CODE>+</CODE></B> 支持方面的动态部署。<BR><BR></BLOCKQUOTE>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Spring AOP</B></P>
<BLOCKQUOTE xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><B><CODE>-</CODE></B> 只能通知那些通过框架的代理机制实例化的对象。<BR><BR><B><CODE>-</CODE></B> 不适合细致的方面。<BR><BR><B><CODE>-</CODE></B> 缺少处理方面的 IDE 支持。<BR><BR><B><CODE>+</CODE></B> 简单的连接点模型很适于粗粒度的方面，更容易学习。<BR><BR><B><CODE>+</CODE></B> Spring 框架集成，易于现有 Spring 用户采用。<BR><BR><B><CODE>+</CODE></B> 跨应用服务器的方面库可移植性。<BR><BR></BLOCKQUOTE>
<P><A name=IDARDIAC><SPAN class=atitle2>结束语</SPAN></A><BR>AOP 工具目前的成就让人对它的发展前景感到兴奋，之所以特别有兴趣在这里研究这 4 种工具，是因为它们目前的成熟度，以及对它们未来开发的展望。这里选择进行比较的 4 种工具都足够成熟，均适用于商业开发，并且会在将来的某个时候获得成功。</P>
<P>仔细分析这篇由两部分构成 AOP 工具比较系列文章中讨论的该工具的利弊，这些有助于判断哪种工具最适合您的项目。文中指出了工具处理方面声明、编织以及构建集成的主要区别，概述了关键的性能问题；还强调了 IDE 集成的好处。本文概述了 Java 语言扩展的优势与不足，这个主题对 Java 开发人员有深远的意义，文章还指出了 AOP 工具的一些未来发展方向。</P>
<P>在阅读本文时，读者可能会很惊讶地发现这些工具的相同点要多于它们的不同点。这意味着不管选择哪项技术，学习曲线可以从一个 AOP 工具转移到另一个。每种工具的新发展会继续相互渗透。AOP 工具目前正在迅速发展，可以满足不断增长的用户社区的需求；而且它还在不断发布新版本。不管您最后采用什么样的 AOP 工具，都鼓励您加入它的用户讨论列表。您的反馈会帮助这项重要的技术指明未来的发展方向。</P>
<P>记着下个月继续关注 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AOP@Work</I> 系列的下一期文章：Ramnivas Laddad 的 “元数据和 AOP：天生绝配”。</P>
<P><A name=resources><SPAN class=atitle2>参考资料 </SPAN></A>
<UL>
<LI>您可以参阅本文在 developerWorks 全球站点上的 <A href="http://www.ibm.com/developerworks/java/library/j-aopwork2" target=_blank xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">英文原文</A>。<BR><BR>
<LI>请参阅 <A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AOP@Work: AOP 工具比较，第 1 部分</A>（developerWorks，2005 年2 月），深入比较 AOP 工具的方面声明风格、AOP 语法和语义。<BR><BR>
<LI>Eclipse.org 中包括关于 <A href="http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/aj5announce.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AspectJ and AspectWerkz joining forces</A> 的最新新闻稿。<BR><BR>
<LI>请参阅 Eclipse 项目，学习更多关于 <A href="http://eclipse.org/aspectj/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AspectJ</A> 的知识。<BR><BR>
<LI>Codehaus 中包含有关 <A href="http://aspectwerkz.codehaus.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AspectWerkz</A> 的信息。<BR><BR>
<LI>要了解关于JBoss AOP 的更多内容，请参阅 <A href="http://www.jboss.org/products/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">JBoss</A>。<BR><BR>
<LI>Spring 框架的 Web 站点中包括关于 <A href="http://www.springframework.org/docs/reference/aop.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Spring AOP</A> 的信息。<BR><BR>
<LI>要学习更多 Java 平台上的 AOP 的基础知识？可以从 Nicholas Lesiecki 撰写的 <A href="http://www-900.ibm.com/developerWorks/cn/java/j-aspectj/index.shtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">使用面向 Aspect 的编程改进模块性</A>（developerWorks，2002 年 1 月）开始。<BR><BR>
<LI>在 <A href="http://www.ibm.com/developerworks/rational/library/2782.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">A look at aspect-oriented programming</A>（<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">The Rational Edge</I>，2004 年 1 月）中，Gary Pollice 用一个登录示例，介绍了 AOP 的基本概念。<BR><BR>
<LI>请参阅 <A href="http://www.ibm.com/developerworks/java/library/j-ajdt/index.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Aspect-oriented development with Eclipse and AJDT</A> （developerWorks，2004 年 9 月），以便更深入地了解这里研究的 AJDT 特性。<BR><BR>
<LI>可以在 codehaus.org 找到当前的 <A href="http://docs.codehaus.org/display/AW/AOP+Benchmark" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AWBench</A> 基准。<BR><BR>
<LI>本文第 1 部分使用的 <CODE>Account</CODE> 示例最初出现在 Ramnivas Laddad 的 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><A href="http://devworks.krcinfo.com/WebForms/ProductDetails.aspx?ProductID=1930110936">AspectJ in Action</A></I>（Manning，2003 年）中。<BR><BR>
<LI>表 1（在第 1 部分中也有）中的用户基数调查是以最初出现在 <A href="http://www.aosd.net/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">aosd.net</A> 上的信息为基础，aosd.net 是每年召开的“面向方面软件开发”会议的主页。<BR><BR>
<LI>在 <A href="http://www.ibm.com/developerworks/cn/java/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><I>developerWorks</I> Java 技术专区</A> 可以找到数百篇有关 Java 各个方面的技术文章。<BR><BR>
<LI>要得到本文作者撰写的更多 AOP 文章、论文和演示文档，请参阅 <A href="http://kerstens.org/mik" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">他的 Web 站点</A>。<BR><BR>
<LI>可以在 developerWorks 的 <A href="http://www.ibm.com/developerworks/cn/java/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Java 技术专区 </A>找到关于 Java 编程各个方面的文章。<BR><BR>
<LI>请参阅 <A href="http://devworks.krcinfo.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Developer Bookstore</A>，获得技术书籍的完整清单，其中包括数百本 <A href="http://devworks.krcinfo.com/WebForms/ProductList.aspx?search=FreeText&amp;SearchT=Keyword&amp;txtSearch=java" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Java 相关主题</A> 的书籍。<BR><BR>
<LI>请参阅 Java 技术专区，从 developerWorks 那里获得侧重于 Java 的免费 <A href="http://www.ibm.com/developerworks/cn/cnedu.nsf/java-onlinecourse-bytitle?OpenView%26Count=500" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">教程</A> 的完整清单。<BR></LI></UL>
<P></P>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><A name=author1></A><SPAN class=atitle2>关于作者</SPAN><BR>Mik Kersten 是一流的面向方面的编程专家，也是 AspectJ 和 AJDT eclipse.org 项目的参与者。作为 Xerox PARC 的研究科学家，他为 AspectJ 构建了 IDE 支持。他正在不列颠哥伦比亚大学攻读博士学位，他的主要工作是使 IDE 更加面向方面。他也向构建开发工具的公司提供咨询，帮助公司利用、支持面向方面的编程技术。 </TD></TR></TBODY></TABLE><BR clear=all><IMG height=10 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=100 border=0><BR></TD></TR></TBODY></TABLE></P><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/1990.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2005-03-13 16:20 <a href="http://www.blogjava.net/jinfeng_wang/archive/2005/03/13/1990.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IBM －AOP@Work: AOP 工具比较，第 1 部分（zz）</title><link>http://www.blogjava.net/jinfeng_wang/archive/2005/03/13/1989.html</link><dc:creator>jinfeng_wang</dc:creator><author>jinfeng_wang</author><pubDate>Sun, 13 Mar 2005 08:18:00 GMT</pubDate><guid>http://www.blogjava.net/jinfeng_wang/archive/2005/03/13/1989.html</guid><wfw:comment>http://www.blogjava.net/jinfeng_wang/comments/1989.html</wfw:comment><comments>http://www.blogjava.net/jinfeng_wang/archive/2005/03/13/1989.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jinfeng_wang/comments/commentRss/1989.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jinfeng_wang/services/trackbacks/1989.html</trackback:ping><description><![CDATA[<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD><SPAN class=astitle>原文地址：<A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml">http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml</A><BR>英文地址：<A href="http://www-128.ibm.com/developerworks/java/library/j-aopwork3/">http://www-128.ibm.com/developerworks/java/library/j-aopwork3/</A><BR><BR><BR>AOP@Work: </SPAN><SPAN class=atitle>AOP 工具比较，第 1 部分</SPAN></TD>
<TD width=8><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=8 border=0></TD>
<TD align=right width=180><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=180 border=0><BR><NOBR></NOBR></TD>
<TD width=6><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=6 border=0></TD></TR>
<TR vAlign=top>
<TD bgColor=#000000 colSpan=5><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=100 border=0></TD></TR>
<TR vAlign=top>
<TD bgColor=#ffffff colSpan=5><IMG height=8 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=100 border=0></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR vAlign=top>
<TD width=5><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=5 border=0></TD>
<TD width="100%">
<TABLE cellSpacing=0 cellPadding=0 width=168 align=right border=0>
<TBODY>
<TR>
<TD width=8><IMG height=21 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=5></TD>
<TD width=160>
<TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
<TBODY>
<TR>
<TD width=160 bgColor=#000000 height=1><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD align=middle background=/developerworks/cn/i/bg-gold.gif height=5><B>内容：</B></TD></TR>
<TR>
<TD width=160 bgColor=#666666 height=1><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
<TBODY>
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#IDAVCESB">选择成熟的工具</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#IDAXEESB">都是为了连接点</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#IDAHZJSB">方面比较</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#IDAQ4JSB">语法差异</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#IDASAKSB">语义的相似性</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#IDAODKSB">语言机制</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#IDALFKSB">结束语</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR><!--Standard links for every dw-article-->
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#resources">参考资料 </A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#author1">关于作者</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#rating">对本文的评价</A></TD></TR>
<TR>
<TD><IMG height=10 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
<TBODY>
<TR>
<TD width=160 bgColor=#000000 height=1><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD align=middle background=/developerworks/cn/i/bg-gold.gif height=5><B>相关内容：</B></TD></TR>
<TR>
<TD width=160 bgColor=#666666 height=1><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=1 width=160 border=0>
<TBODY>
<TR>
<TD><A href="http://www.ibm.com/developerworks/library/j-aopwork2/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AOP Tool comparison, Part 2: Development environments</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www.ibm.com/developerworks/rational/library/2782.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">A look at aspect-oriented programming</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www.ibm.com/developerworks/java/library/j-ajdt/index.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Aspect-oriented development with Eclipse and AJDT</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
<TBODY>
<TR>
<TD width=160 bgColor=#000000 height=1><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD align=middle background=/developerworks/cn/i/bg-gold.gif height=5><B>订阅:</B></TD></TR>
<TR>
<TD width=160 bgColor=#666666 height=1><IMG height=1 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD>
<TABLE cellSpacing=0 cellPadding=1 width=160 border=0>
<TBODY>
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/newsletter/index.html">developerWorks 时事通讯</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD><A href="http://www-900.ibm.com/developerworks/cn/subscription/index.shtml">developerWorks 订阅<BR xmlns:fo="http://www.w3.org/1999/XSL/Format">(订阅CD 和下载)</A></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD height=1><IMG height=5 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=0 cellPadding=0 width=160 border=0>
<TBODY>
<TR>
<TD width=150 bgColor=#000000 colSpan=2 height=2><IMG height=2 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR>
<TR>
<TD width=150 bgColor=#ffffff colSpan=2 height=2><IMG height=2 alt="" src="http://www-900.ibm.com/developerworks/cn/i/c.gif" width=160></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><SPAN class=atitle2>语言机制</SPAN><BR>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR vAlign=top align=left>
<TD>
<P>级别: 中级</P></TD></TR></TBODY></TABLE>
<P><A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#author1"><NAME>Mik Kersten</NAME></A><BR>AOP 工具构建师、咨询顾问, University of British Columbia<BR>2005 年 2 月 </P>
<BLOCKQUOTE><ABSTRACT-EXTENDED>AOP 技术的时代已经来临，但是怎样才能为项目选择正确的工具呢？在新推出的 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AOP@Work</I> 系列的第一篇文章中，面向方面（aspect-oriented）的编程专家 Mik Kersten 将比较 4 个领先的 AOP 工具（AspectJ、AspectWerkz、JBoss AOP 和 Spring AOP），帮助大家判断应该选择哪一个工具。本文由两个部分组成，在文中，作者将重点介绍这些工具的语言机制和不同技术的优劣。他分别用 4 种工具编写同一个示例，让读者感觉到它们之间的高级区别。他还将讨论每种工具的语法技术对 AOP 语义产生的效果。在文章结束时，作者将对工具的核心语言机制（例如切入点匹配和组合、通知的格式、连接点上下文）进行深入比较。<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">注意，本文将解释最近宣布的 AspectJ 和 AspectWerkz 项目合并的意义。</I></ABSTRACT-EXTENDED></BLOCKQUOTE>
<P>面向方面编程（AOP）在 Java™ 平台上变得日益流行。随着 AOP 出版物和会议的增加，这项技术的工具与实现越来越多。虽然人们很清楚 AOP 是面向对象技术的补充，但是 Java 开发人员该如何评估当前的 AOP 工具，特别是每项新技术实现的优劣，这方面则相对不那么清楚。</P>
<P>本文有两部分，而且本文还是 developerWorks 上一个新的 AOP 系列的第一篇文章。在本文中，将概述 AOP 工具当前的技术状况，比较对于该技术而言最成熟的一些方法：AspectJ、AspectWerkz、JBoss AOP、和 Spring AOP，并对比与每种方法的采用有关的问题。文中还会解释最近宣布的 AspectJ 和 AspectWerkz 项目合并的意义（请参阅<A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#resources" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">参考资料</A>）。</P>
<P>本文无意作为 AOP 的介绍或某个特定 AOP 实现的入门读物。而是将对目前使用最普遍的 AOP 技术进行概述。对每个工具的语言机制和工具支持的内在优劣进行探讨，将有助于为项目选择最合适的技术。这里定义的指标还会让读者更加容易地评估即将推出的 AOP 工具和特性。关于 developerWorks 上介绍 AOP 的最新文章列表，请参阅<A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#resources" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">参考资料</A>。</P>
<P>请注意本文有两个部分，为了方便读者，两部分同时发布。第 1 部分侧重于这 4 个领先工具各自的 AOP 语言机制处理技术，其中包括工具的方面语法（aspect syntax）和切入点的表示、用来声明方面的机制范围等主题。<A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#part2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">第 2 部分</A>继续深入介绍领先的 AOP 实现如何与现有的开发环境、工具和库进行集成。这一部分包括以下主题：方面设计器、IDE 插件、可伸缩性和 AOP 工具将来的发展方向，还包括对最近 AspectJ 和 AspectWerkz 项目合并的关注。</P>
<P><A name=IDAVCESB><SPAN class=atitle2>选择成熟的工具</SPAN></A><BR>AOP 是一项新技术，所以，并不是现有的所有工具都已经成熟到适用于商业开发。判断成熟度的一个主要因素是用户的采用程度。在考虑把一项新编程技术应用到商用之前，这项技术必须从活跃的用户社区的反馈中得到强化。表 1 显示了 aosd.net 上列出的目前可以使用的 AOP 工具（请参阅<A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#resources" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">参考资料</A>）。每个工具的用户列表贴子数量可以表明它的用户基数（省略了贴子的实际数量，因为单独一个月的统计可能给读者造成误解）。</P>
<P><A name=table-survey><B>表 1. 在 2004 年 11 月 AOP 工具用户列表中的贴子数量</B></A><BR><IMG height=160 alt="" src="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/table-survey.gif" width=600 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="30%" align=right border=1>
<TBODY>
<TR>
<TD background=/developerworks/cn/i/bg-gold.gif>
<P><A name=sidebar1><B>关于这个系列</B></A><BR><I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AOP@Work</I> 系列面对的是在面向方面编程上有些基础，同时想扩展或加深这方面了解的开发人员。同 developerWorks 的大多数文章一样，这个系列非常实用：读完每篇介绍新技术的文章，都可以立即将其投入使用。</P>
<P>为这个系列选择的每个作者都是面向方面编程领域的领导或专家。许多作者都是系列文章中介绍的项目和工具的参与者。每篇文章都力图提供一个中立的评述，以确保这里表达的观点的公正与正确。</P>
<P>请就文章的评论或问题分别与这些文章的作者联系。要对这个系列整体进行评论，可以与这个系列的负责人 <A href="mailto:ndlesiecki@yahoo.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Nicholas Lesiecki</A> 联系。</P>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">关于本文</B><BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">本文并不想突出某一个工具，而是要用一种批判的、没有偏见的方式突出每个工具的优势与不足。虽然作者是 AspectJ 项目的参与者之一，但是在编写本文的时候，也咨询了其他 AOP 工具项目的领导人，以确保公平地展示所讨论的技术。</P></TD></TR></TBODY></TABLE></P>
<P>请注意 Spring 的 AOP 部分没有形成一个独立的下载或用户社团，所以用户基数相当比例的用户可能没有给 Spring AOP 发贴，而是投在别的主题上了。在 aosd.net 上还列出了 4 个额外的工具，但是它们要么缺乏用户讨论论坛，要么在 11 月没有贴子。</P>
<P>AOP 工具虽然没有列在表中前四位，但它在技术上可能非常成熟，可是缺乏较大的用户基数就意味着它们还没有经受过采纳程度测试。虽然在本文编写的时候，它们还不适合于商业开发，但是这些工具的日后发展还是值得关注的。通过上表的比较，还可以看出非 Java 平台的 AOP 工具没有 Java 平台的工具成熟，但是应当注意 .NET 和 C++ 工具的用户社区正在成长。</P>
<P>根据表 1，可以看出，从用户采用度的角度来说，AspectJ、AspectWerkz、JBoss AOP 和 Spring AOP 是领先的工具。所有这些工具都是适合用于商业开发中的开源项目。按字母顺序将它们排列如下，包括它们 V1.0 版本的发布日期：</P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI><B>AspectJ</B> —— 2001 年由 Xerox PARC 的 AOP 小组发行。目前主页在 eclipse.org 上，由 IBM 支持。版本已经更新到 1.2.1。<BR><BR>
<LI><B>AspectWerkz</B> —— 2002 年发布，由 BEA Systems 支持。版本更新到 2.0RC2。<BR><BR>
<LI><B>JBoss AOP</B> —— 2004 年作为 JBoss 应用程序服务器框架的扩展发布。版本更新到 1.0。<BR><BR>
<LI><B>Spring AOP</B> —— 2004 年作为 Spring 框架的扩展发布。版本更新到 1.1.3. <BR><BR></LI></UL>
<P><A name=IDAXEESB><SPAN class=atitle2>都是为了连接点</SPAN></A><BR>本文介绍的每个 AOP 工具都采用了连接点（join point）模型和机制，显式地声明程序的横切结构。虽然各个工具实现这个框架的技术非常相似，但是理解底层机制对于了解每项技术的优劣是非常重要的。在这一节中，将回顾 AOP 的连接点模型以及利用连接点模型的语言模型。</P>
<P><A name=IDA3EESB><SPAN class=atitle3>支持机制</SPAN></A><BR>AOP 工具的设计目标是把横切的问题（例如认证和事务管理）模块化。在单独使用面向对象技术实现的的时候，处理这些问题的代码会分散在整个系统中，这种分散造成管理和发展横切结构时出现不必要的困难。与对象提供了一种能够清楚地捕获继承结构的语言机制类似，AOP 也为横切问题的良好模块化提供了同样的好处。位于每个 AOP 工具核心的是<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">连接点模型</I>，它提供了一种机制，可以识别出在哪里发生了横切。</P>
<P><I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">连接点</I> 就是主程序和方面相遇的地方。静态连接点允许方面定义类上的新成员。动态连接点是方面执行与程序执行相遇的地方。例如，普通的 Java 程序执行方法调用、字段设置这样的连接点。再比如说，请考虑一下这样一个问题：对改变 <CODE>Account</CODE> 状态的活动进行监视，就像在 Ramnivas Laddad 的 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AspectJ in Action</I> 一书中讨论的那样（请参阅<A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#resources" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">参考资料</A>）。 图 1 中的顺序图突出了在 <CODE>Account</CODE> 操作上形成的一些动态连接点。</P>
<P><A name=figure1><B>图 1. 突出了选中的动态连接点的 UML 序列图</B></A><BR><IMG height=481 alt="" src="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/figure-sequence.gif" width=455 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>下面的编号与图中的编号对应：</P>
<OL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI><I>方法执行</I> 连接点，与方法返回之前的生命周期对应。<BR><BR>
<LI><I>控制流程</I> 捕捉在控制流程序列中出现的各个连接点；在这个例子中，在 <CODE>debit()</CODE> 方法调用下方的序列描述了在 <CODE>debit()</CODE> 调用中发生的全部连接点。<BR><BR>
<LI><I>字段访问</I> 连接点对应着字段的读和写；在这个例子中，在 <CODE>Account</CODE> 类上对 <CODE>name</CODE> 字段进行了赋值。</LI></OL>
<P>
<TABLE cellSpacing=0 cellPadding=5 width="30%" align=right border=1>
<TBODY>
<TR>
<TD background=/developerworks/cn/i/bg-gold.gif>
<P><A name=sidebar2><B>AspectJ 和 AspectWerkz 项目合并</B></A><BR>AOP 技术正在迅速地向前发展，在本文的<A href="http://www.ibm.com/developerworks/library/j-aopwork2/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">第 2 部分</A>突出了领先的 AOP 工具的预计的发布计划。有一个那些思想超前的读者会特别感兴趣的主题，这就是最近 AspectJ 与 AspectWerkz 项目的合并，这一合并会给 AOP 的发展前景带来重大的变化。一些开发人员在这些项目上进行合作，生产 AspectJ 5，这是一种单一工具，融合了这里介绍的 AspectJ 和 AspectWerkz 的语法。</P>
<P>重要的是要注意 AspectWerkz 并没有正在消失。它将成为编写 AspectJ 程序的另一种方法，并更名为 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">@AspectJ 风格</I>。在这里可以看到，语法是 AOP 实现之间的主要区别因素，而核心的 AOP 机制通常非常相似。 AspectWerkz 和 AspectJ 的相似性使得这两种技术可以联合。合并可以在提供方面语法的时候提供更多的灵活性，同时保留着关键的好处（例如静态类型化和成熟的工具支持）。有关合并的细节以及相关文档，可以从<A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#resources" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">参考资料</A>中得到。虽然本文重点放在立刻就可以开始使用的工具上，但是这里概述的指标和优劣也适用于未来的发行版（例如 AspectJ 5）。</P></TD></TR></TBODY></TABLE></P>
<P><A name=IDAVHESB><SPAN class=atitle3>切入点、通知和类型间声明</SPAN></A><BR>AOP 工具提供了识别连接点集合的机制，叫作<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">切入点（pointcut）</I>。<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">通知（advice）</I> 机制指定在程序执行过程中遇到匹配的切入点时应当采取什么行动。另外，类型间声明（inter-type declaration）（开放类或混合类提供了在现有类型上声明额外成员的方法。切入点、通知和类型间声明组合在一起，使 AOP 语言可以清楚地表达横切问题。<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">方面</I> 声明可以在标准的 Java 字段和方法之外包含这三类成员。方面代表一套模块化良好的横切结构。如下所示，不同的 AOP 技术实现这些方法的技术各不相同。但是，每种技术的核心，都是连接点的访问、编辑、命名和抽象机制。</P>
<P>切入点可以通过显式枚举方式描述连接点集合。应当用一个示例指定<A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#figure1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 1</A> 所示的 <CODE>Account</CODE> 的利息的三个方法调用。虽然枚举可能很有用，但是用结构化属性的方式表示连接点通常更方便。这类基于属性的切入点可以表示一套与“每个针对 <CODE>Account</CODE> 子类型的调用”匹配的连接点，却不必强迫程序员枚举这些子类型。这样做可以保证向系统添加由 <CODE>Account</CODE> 扩展的新类时，新类会自动与切入点匹配。</P>
<P>切入点支持<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">复合（composition）</I>，这就允许把简单的切入点组合成更复杂的切入点。例如，可以把所有 <CODE>Account</CODE> 调用的切入点限制在那些针对特定类或控制流程进行的调用中。切入点的<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">命名（naming）</I>机制提高了可读性和复合性。对<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">抽象（abstraction）</I>与<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">具体化（concretization）</I>的支持，可以更加容易地创建通用库，对于要应用库的特定应用程序的切入点来说，这些库可以独立定义。最后，对切入点中<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">公开连接点状态</I> 的支持允许对诸如正在执行对象和方法参数之类的访问事项进行商量。</P>
<P><A name=IDAHZJSB><SPAN class=atitle2>方面比较</SPAN></A><BR>如前所述，所有 AOP 工具的底层机制都是连接点和切入点、通知和类型间声明的概念。在这些工具中，可以注意到的主要区别就是方面声明编写及应用到系统上的方式。这些工具可用以下方法中的一种进行方面声明：使用类似 Java 的代码、注释或 XML。对于某些开发人员来说，熟悉用 Java 语言编程方面的知识，要比熟悉语言扩展技术的优劣更重要，这些内容会在后面的小节中讨论。对于其他人来说，了解注释和 XML 技术在集成上的优势，要比痛苦地把切入点当作字符串来操作更重要。</P>
<P>在这一节中，将使用一个常见的示例指出每个工具在方面声明技术上的差异。请考虑<A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#figure1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 1</A> 所示的 <CODE>Account</CODE> 类的授权策略这样一个示例。在面向对象的实现中，最常见到的，就是对认证的调用分散在 <CODE>Account</CODE> 类的众多方法以及需要认证的其他类中。在 AOP 实现中，可以明确地用一个方面捕获这个行为，而不必修改操纵帐户的代码。不管使用什么工具声明，这个方面都需要具备以下特征：</P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI>一个<I>切入点</I>，捕捉 <CODE>banking.Account</CODE> 类上所有公共方法的执行。<BR>
<LI>一种引用正在认证的 <CODE>Account</CODE> 的方式。<BR><BR>
<LI><I>通知</I>，在切入点指定的连接点上调用 <CODE>Account</CODE> 的认证。</LI></UL>
<P>现在，请看这几个领先的 AOP 工具各自是如何处理这个方面的。</P>
<P><A name=IDAV0JSB><SPAN class=atitle3>AspectJ</SPAN></A><BR>Aspect 中的方面声明类似于 Java 语言中的类声明，如图 2 所示。由于 AspectJ 是 Java 语言语法和语义的扩展，所以它提供了自己的一套处理方面的关键字。除了包含字段和方法之外，AspectJ 的方面声明还包含切入点和通知成员。示例中的切入点使用了修饰符（modifier）和通配符（wildcard）模式来表达“所有公共方法”。对帐户的访问，由 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">pointcut</I> 参数提供。通知使用这个参数，而切入点则用 <CODE>this(account)</CODE> 把它绑定。这样做的效果，就是捕获了正在执行的方法所隶属 <CODE>Account</CODE> 对象。否则，通知的主体与方法的主体相似。通知可以包含认证代码，或者就像在这个示例中一样，可以调用其他方法。</P>
<P><A name=figure2><B>图 2. AspectJ 的方面 </B></A><BR><IMG height=222 alt="" src="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/figure-aspectj.gif" width=579 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>构建 AspectJ 程序与构建 Java 程序类似，其中包括调用 AspectJ 的递增编译器，构建所有的项目源文件，包括普通的 Java 源文件。运行 AspectJ 程序也与运行 Java 程序一样，请注意要把 <CODE>aspectjrt.jar</CODE> 库添加到类路径中。要对在系统中应用哪个方面进行配置，必须把它们加入包含列表或从中删除，包含列表会传递给编译器，可以通过 IDE 支持传递包含列表，如果正在 Ant 环境或命令行进行工作，也可以通过“.lst” 包含文件传递。注意，在第 2 部分中，将讨论构建 AOP 程序的细节以及方面设计的概念。</P>
<P><A name=IDAX1JSB><SPAN class=atitle3>AspectWerkz</SPAN></A><BR>AspectWerkz 和 AspectJ 之间的重要区别就是： <CODE>Authentication</CODE> 现在是一个普通的 Java 类，而不是一个方面。AspectWerkz、JBoss AOP 和 Spring AOP 都在没有改变 Java 语言语法的情况下加入了方面语义。AspectWerkz 提供了两种进行 AOP 声明的途径。最常用的是注释，注释可以采用图 3 中的 Java V5.0 风格，也可以为了与 J2SE V1.4 兼容采用 Javadoc 风格。AspectWerkz 还支持另外一种基于 XML 的方面声明风格。XML 风格与下面介绍的 JBoss AOP 的风格类似，把方面声明放在单独的 XML 文件中。</P>
<P>请注意通知就是普通的方法声明。按照约定，它被当作不同类型的方法声明，因为不应当显式地调用它，而是应该在满足特定切入点时自动运行它。AspectWerkz 的切入点声明是附加到切入点“方法”的字符串值，也可以在 XML 文件中独立存在。所以，没有切入点的 <CODE>import</CODE> 机制，所有的类型引用必须完全规范。对正在运行的 <CODE>Account</CODE> 对象的访问技术与 AspectJ 相同。请注意，规划的 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">@AspectJ</I> 语法看起来与 AspectWerkz 注释的语法非常相似。</P>
<P><A name=figure3><B>图 3. AspectWerkz 的方面</B></A><BR><IMG height=391 alt="" src="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/figure-aspectwerkz.gif" width=579 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>构建 AspectWerkz 程序会涉及一个标准的 Java 构建，然后会涉及到后处理。要运行 AspectWerkz 程序，必须把 AspectWerkz 库放在类路径中。在使用不可插入的方面的情况下，由 aop.xml 文件配置系统中一些方面的包含情况。</P>
<P><A name=IDA02JSB><SPAN class=atitle3>JBoss AOP</SPAN></A><BR>JBoss AOP 基于 XML 的方面来声明风格，如图 4 所示。JBoss 也支持与图 3 所示相似的注释风格。在 XML 风格中，方面、切入点和通知声明都以 XML 形式表示的。通知的实现，用的是普通的 Java 方法，由 JBoss AOP 框架调用。切入点和切入点到通知的绑定都在方面中用 XML 注释声明。JBoss 没有显式地绑定 <CODE>Account</CODE> 参数，而是提供了对当前正在执行的对象的反射访问，因此需要把类型转换到对应的类型。注意，即将发布的 JBoss 会提供一些静态类型的切入点参数来解决这一问题。</P>
<P><A name=figure4><B>图 4. JBoss AOP 的方面 </B></A><BR><IMG height=364 alt="" src="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/figure-jboss.gif" width=588 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>用 JBoss 构建方面只包括普通的 Java 构建。JBoss AOP 的运行时截取框架（interception framework）负责管理切入点匹配和通知调用。需要对启动和类路径做一些配置，但是 JBoss AOP 的 IDE 插件替用户做了这些工作。方面在 jboss-aop.xml 文件中配置。</P>
<P><A name=IDAR3JSB><SPAN class=atitle3>Spring AOP</SPAN></A><BR>查看图 5 中的 Spring AOP 示例时，可以注意到其中的 XML 比前面介绍的技术多。与 JBoss AOP 类似，Spring 的通知实现是带有特殊参数的 Java 方法，由 Spring 框架调用。XML 描述 <CODE>accountBean</CODE>，Spring 框架通过它访问 <CODE>Account</CODE> 对象，包括通知使用的拦截器 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">advisor</I> 及其匹配模式，还有应用到模式的<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">向前（before）</I> 通知。</P>
<P><A name=figure5><B>图 5. Spring AOP 的方面 </B></A><BR><IMG height=579 alt="" src="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/figure-spring.gif" width=584 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>Spring AOP 的技术虽然提供了更加精细的配置，但在将它用于 XML 时，它与 JBoss AOP 非常类似。构建、运行和配置 Spring AOP 方面的过程与 JBoss AOP 相同，但 Spring AOP 依赖的是 Spring 框架方便的、最小化的运行时配置，所以不需要独立的启动器。请注意，使用这个技术，只能通知从 Spring 框架检索出的对象。</P>
<P><A name=IDAQ4JSB><SPAN class=atitle2>语法差异</SPAN></A><BR>正如上面的图所展示的，AOP 工具之间的关键差异就是处理方面声明的方式。AspectJ 是 Java 语言的扩展，用它可以完全在代码中对方面进行声明。AspectWerkz 和 JBoss AOP 支持用方面元数据对 Java 代码进行注释，或者在独立的 XML 文件中对方面进行声明。在 Spring AOP 中，则完全用 XML 对方面进行声明。所以，在三种不同的技术中，对方面进行编程的感觉可能非常不同。用 AspectJ 的<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">代码风格</I>，方面和切入点声明感觉起来就像 Java 代码。而用 JBoss AOP 或 AspectWerkz 的<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">注释风格</I>，感觉起来就像在现有 Java 元素上做的附加标签。而用 Spring AOP 风格，以及 AspectWerkz 和 JBoss AOP 的 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">XML 风格</I> 时，感觉就像使用独立的声明性 XML 语言。</P>
<P>每种技术都有它的优势，具体要由使用者决定哪个更适合需求。所以在这一节，将简要地讨论一些能够有助于进行决策的要点。</P>
<P><A name=IDA44JSB><SPAN class=atitle3>自己的风格是什么？</SPAN></A><BR>不管选择哪个 AOP 工具，使用通知主体时只涉及到使用 Java 代码。如果需要修改切入点，那么区别是非常透明的。在使用 XML 风格时（就像在 Spring AOP 中），修改切入点包括：从通知找到 XML 文件中对应的切入点声明。从正面来说，这项技术把切入点和方面配置的工作全都局限于本地，但是如果要编辑许多通知和切入点，而且要在 Java 和 XML 之间重复地翻来覆去，那么这项工作就会变得很繁琐。</P>
<P>如果使用 AspectWerkz 或 JBoss AOP 提供的注释风格，那么就可以把切入点的表达值从 XML 转移到 Java 成员的注释。这样可以更容易地并发处理通知体和切入点。如果选择了 AspectJ 的代码风格，那么就会发现处理切入点感觉就像处理代码，而不像是处理非结构化的字符串值。从 Java 代码能得到的一切（例如“import”语句），都可以用于切入点。对比之下，如果用 AspectWerkz、JBoss AOP 和 Spring AOP 的 XML 和注释风格，总是需要在规范切入点中的类型引用。</P>
<P><A name=IDAF5JSB><SPAN class=atitle3>简洁还是繁琐？</SPAN></A><BR>方面声明的风格对每个工具中使用的方面有很大的影响。例如，支持在 XML 中声明方面的工具，也支持在同一 XML 文件中对方面应用到系统的方式进行配置。在前面的小节中，只展示了切入点和方面声明，但是类型间声明同样受到风格选择的影响。在 AspectJ 中，类型间方法声明看起来就像正常的方法声明，引用的技术也一样。而在其他技术中，则要指定一个类，扩展额外的混合类并继承那些额外的成员，通过注释或 XML 添加新方法。注意，目前 AspectJ 是惟一提供使用切入点的静态强制机制的工具。表 2 比较了这些工具对 AOP 语法的关键元素的处理技术。</P>
<P><A name=table2><B>表 2. 比较领先的 AOP 工具中的语法</B></A><BR><IMG height=122 alt="" src="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/table-syntax.gif" width=600 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>显然，从图 2-5 的方面声明来看，代码风格是处理 AOP 声明最简洁的技术。它不需要对通知命名，也不需要显式地调用通知。代码风格不需要显式地把通知绑定到切入点（就像 XML 风格那样），也不需要把通知绑定到 <CODE>return</CODE> 语句（这是 AspectWerkz 的切入点“方法”所需要的）。对于可以在 <A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#figure3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 3</A> 和 <A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#figure4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 4</A> 的 XML 中看到的复杂设计，AspectJ 对 Java 语言进行的语法扩展允许直接表示这些设计。用 AspectJ 编写方面，感觉起来更像是编写 Java 代码，避免了冗余的键入，因此出错也就更少。从不好的一面来说，Java 的语法扩展代价巨大，而注释和 XML 风格有它们独特的优势。最明显的就是 XML 风格可以控制切入点和通知的绑定。这对于扩展和配置方面非常有益，在下面一节中将讨论这点以及不同风格带来的其他优缺点。</P>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">代码风格与注释和 XML 的比较</B><BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">那么，应当采用代码风格，还是用注释或 XML 声明方面呢？以下是基于 AspectJ 的 Java 代码的一些技术的优缺点总结：</P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI>简明语法充分利用对 Java 代码的熟悉，减少键入错误，使错误更少。 
<LI>切入点是一级实体，因此更容易对它们进行处理。 
<LI>对于许多开发人员，用 XML 进行声明性编程要比用 Java 语言扩展更熟悉。 
<LI>通知到切入点的绑定不能由开发人员控制。</LI></UL>
<P>如果这个小结仍然无法缩小决策范围，那么不要担心。除了用每种风格编写这些方面的感觉之外，还有更多需要考虑的东西。当在下一节中查看语义的时候，语法决策还会出现，而且也会影响在第 2 部分中讨论的工具支持。</P>
<P><A name=IDASAKSB><SPAN class=atitle2>语义的相似性</SPAN></A><BR>虽然工具的方面声明风格之间存在主要的语法差异，但是核心的 AOP 语义是类似的。每个工具都有完全相同的连接点模型的概念，都把连接点作为 Java 程序中的关键点，把切入点作为匹配连接点的机制，把通知作为指定连接点匹配时执行操作的机制。</P>
<P><A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#table3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">表 3</A> 和 <A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#table4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">表 4</A> 总结了每种技术的语义。您可以注意到，命令规范上有许多微小的差异和变化，但是各种技术最终聚合在相同的核心概念上。这种聚合有很大的好处，因为这意味着学习曲线很容易从一项 AOP 技术转移到另外一项 AOP 技术。剩下来要考虑的就是每种技术的差异所带来的优劣了。</P>
<P><A name=IDABBKSB><SPAN class=atitle3>回到连接点</SPAN></A><BR>一个 AOP 工具连接点模型的表达方式决定了可用的连接点粒度，以及连接点如何匹配。每个 AOP 工具都提供了大量用于连接点匹配的原生切入点。有些原生切入点只与特定类型的连接点匹配（例如，方法执行）。其他切入点能够根据连接点的公共属性（例如，在某个控制流程中的所有连接点）匹配任何类型的连接点。连接点的类型以及它们特定的切入点，可以分成以下几组：</P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI><B>调用（Invocation）</B>—— 调用或执行方法和其他代码元素时的点。<BR><BR>
<LI><B>初始化（Initialization）</B>—— 初始化类和对象时的点。<BR><BR>
<LI><B>访问（Access）</B>—— 读写某些字段时的点。<BR><BR>
<LI><B>异常处理（Exception handling）</B>—— 抛出和处理异常与错误时的点。<BR><BR></LI></UL>
<P>另外，也支持以下没有类型的切入点分类：</P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI><B>控制流程（Control flow）</B>—— 在某个流程控制流程中的连接点。<BR><BR>
<LI><B>包含（Containment）</B>—— 与包含在某个类或方法中的代码位置对应的连接点。<BR><BR>
<LI><B>条件（Conditional）</B>—— 特定预测为真的连接点。</LI></UL>
<P>如表 3 所示，每个工具实现连接点模型的方式，以及它们用来匹配连接点的原生切入点，都略有差异。注意，在某些情况下（在括号中表示），连接点不用切入点标识。</P>
<P><A name=table3><B>表 3. 连接点和用来匹配连接点的原生切入点</B></A><BR><IMG height=258 alt="" src="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/table-pointcuts.gif" width=600 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P><A name=IDAXCKSB><SPAN class=atitle3>要富于表现力还是要简单？</SPAN></A><BR>在这里主要的优劣在于富于表现力和简单性的比较。更加完整和精细的切入点集合允许通过方面访问程序执行中更多有趣的点。例如，与持久性有关的方面可能需要访问对象的初始化连接点。但是这类完整性也会带来额外的复杂性和更陡峭的学习曲线。许多 Java 程序员并不区分调用和执行，而且没有几个人需要理解初始化的微妙之处。而且许多常用的方面被当作是辅助性的，所以是否有表现力与应用程序的功能并没有紧密耦合。在常用的辅助性方面，例如监视和日志，通常只利用了粗粒度的切入点（例如方法执行）。从反面来看，更广泛的切入点集合确实具备量入为出的属性，因为切入点可以边用边学。如果不想用切入点制作程序，那么会造成面向对象代码的强制重构，例如：以 <CODE>init()</CODE> 方法的形式公开类的初始化。</P>
<P>AspectJ 和 AspectWerkz 的连接点模型差不多完全融合，而且已经成为最近的合并的关键促进者之一。JBoss AOP 模型几乎同样有表现力，只是为了简单性而遗漏了一些不太常用的连接点。一个明显的差异是：在 JBoss Aop 中，不能把控制流程表示成“在这个切入点的执行之下的所有连接点”。相反，程序员需要手动列出调用堆栈中的每个调用。</P>
<P>Spring AOP 采用了不同的技术，目的是限制它的连接点模型的表现力。这使它特别容易采用，而且对于一些粗粒度的横切很有用。即将发行的版本将与 AspectJ 集成，提供与精细横切机制的互操作性。</P>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">连接点模型的表现力与简单性的比较</B><BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><BR xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">一些项目可以从更有表现力的连接点模型（例如 AspectWerkz、AspectJ 和 JBoss AOP 提供的）获益，所以最好还是采用 Spring AOP 粗粒度的方便性？以下是更有表现力的模型固有优缺点的一个总结，多考虑一下这些方面会对您有所帮助：</P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI>了解更多知识 。 
<LI>对于粗粒度的横切和辅助性方面，只需要很少的切入点。 
<LI>没有精细的切入点，许多方面就不能表达。 
<LI>使用新切入点的学习曲线是随用随学。</LI></UL>
<P><A name=IDAODKSB><SPAN class=atitle2>语言机制</SPAN></A><BR>我将用每种技术语言机制的详细对比结束 AOP 工具比较的第一部分的讨论。表 4 是 4 个工具的 AOP 语言的概括。下面讨论了最明显的区别。</P>
<P><A name=table4><B>表 4. 领先的 AOP 工具的语义概括</B></A><BR><IMG height=275 alt="" src="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/table-semantics.gif" width=600 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">切入点匹配和复合</B>：AspectJ、AspectWerkz 和 JBoss AOP 提供了类似的类型模式支持。它们三个都允许签名方面的匹配，对于 Java 5 应用程序来说，这些匹配包括注释和泛型。AspectJ 和 AspectWerkz 提供了一种简洁的引用多个类型的技术（例如 <CODE>Account+</CODE> 表示帐户的所有子类型）。所有的工具都支持通配符匹配。Spring AOP 还提供了对正则表达式的支持。虽然这看起来可能是一个强大的优势，但还是要指出其他技术已经选择了放弃正则表达式，好让切入点读起来不是太难，同时不会存在潜在的损害。切入点复合操作符基本上都是相同的。Spring AOP 不提供“非”操作，这个操作通常与没有在 Spring AOP 连接点模型的容器（containment）连接点结合使用。</P>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">通知形式</B>：AspectJ 支持比其他技术更多的通知形式，而 JBoss AOP 只支持一种通知形式。每种通知形式都可以表达成 <CODE>around</CODE> 通知，所以 JBoss 的技术是无限的，而且它确实提供了额外的简单性。不好的一面是它损失了简洁性，这一点可以从需要进行额外的调用才能继续执行原来的方法调用（如 <A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#figure4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 4</A> 所示）看得出来，而如果用 <CODE>before</CODE> 进行通知，这一点就是不必要的。还请注意，强迫通知去遵守普通的 Java 规则（就像注释和 XML 风格做的那样），在一些情况下容易出问题，因为这些规则是为方法设计的。AspectJ 拥有把被通知方法的异常“软化”的能力，这很有用，但是不符合方法异常检测的标准语义。</P>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">连接点上下文</B>：在 AspectJ 和 AspectWerkz 中，通过指定和绑定切入点参数访问动态连接点的状态，类似于在 Java 语言中声明方法参数的技术（请参阅<A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#figure2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 2</A> 和 <A href="http://www-900.ibm.com/developerworks/cn/java/j-aopwork1/index.shtml#figure3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">图 3</A>）。这为连接点上下文提供了静态类型化的好处。JBoss AOP 和 Spring AOP 反射性地访问连接点的状态，这消除了在切入点表达式中参数绑定的复杂性，代价是参数静态类型化。Java 程序员习惯了方法参数静态类型化带来的好处，同时还可以从切入点参数的静态类型化得到同样的好处。所以，在 JBoss AOP 最近的发行版本中，有提供静态类型化的“args” 的计划。</P>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">实例化</B>：在所有的工具中，方面的实例化是由 <CODE>per</CODE> 子句控制的。正如所料，Spring AOP 的实例化模型更简单。对于额外的实例化机制的支持，则意味着可以把方面编写成只能应用于特定的动态上下文环境中，不用编写代码保存这个上下文并测试其他方面是否该应用这个方面。主要的区别因素是 AspectJ 支持在每个控制流程进行方面初始化，AspectWerkz 支持每个线程的初始化，而 JBoss 则支持每个连接点的初始化。哪种最有用则取决于具体的需求。</P>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">扩展性</B>：方面的扩展性支持库方面的部署，这样可以在日后为特定程序而将这些库方面具体化。例如，一个方面库可以提供应用程序监视需要的全部逻辑和基础设施。但是，要采用某个特定项目的库，那么库使用的切入点必须扩展成应用程序特定的连接点。AspectJ 用抽象方面支持扩展性，抽象方面包含抽象的切入点和具体的通知。扩展抽象方面的子方面必须具体化切入点。AspectWerkz 和 JBoss AOP 使用了完全不同的技术，没有使用抽象切入点机制。扩展是通过生成方面的子类、并在 XML 中或通过注释定义新的通知绑定而实现的。切入点到通知的显式绑定为 AspectWerkz 和 JBoss AOP 提供了显著优势，从而可以很容易地把方面扩展到新系统，无需要生成子类。方面库的使用数据正在日益增多，这些将决定与其他技术使用的 Java 风格的继承和切入点绑定相比，AspectJ 特殊的 AOP 继承形式是更好还是更差。</P>
<P>每项技术在处理 AOP 的语言机制时，都提供了自己独特的优缺点。用一个简单的列表来总结这些优缺点是不可能的，因为对于不同的项目，每项技术的好处是各不相同的。但是，以上信息为选择工具或者遇到关键问题时寻找替代品提供了指南。</P>
<P><A name=IDALFKSB><SPAN class=atitle2>结束语</SPAN></A><BR>为项目选择一个 AOP 工具所面临的难题在于比较每种工具的优劣，同时不要让自己迷失其中。AOP工具比较的第一部分强调了 4 种领先的 AOP 技术的核心机制，并对比了它们的相似与不同之处。</P>
<P>如果本文是在十年之前报道一项新的模块化技术，那么我们可能就此打住，开始用自己选择的风格来编写方面 —— 可能是在命令行用 Emacs 或其他文本编辑器构建。但是今天，如果没有深入研究一项新技术如何与现有的开发环境和其他工具集成，人们是不会轻易地考虑采用它的。</P>
<P>所以，<A href="http://www.ibm.com/developerworks/library/j-aopwork2/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">本文的第二部分</A>把重点放在集成因素对 AOP工具选择的影响。在其他因素之中，将讨论每个工具如何处理方面的编译与设计，以及如何依据 IDE 集成与工具支持将它们都组合在一起。我还会比较这些工具的基本特性，看看它们背后到底是什么，包括进一步探讨 AspectJ 与 AspectWerkz 项目合并之后我们可以期盼从中得到什么。</P>
<P><A name=resources><SPAN class=atitle2>参考资料 </SPAN></A>
<UL>
<LI>您可以参阅本文在 developerWorks 全球站点上的 <A href="http://www.ibm.com/developerworks/java/library/j-aopwork1/" target=_blank xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">英文原文</A>。<BR><BR>
<LI>请参阅 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AOP@Work</I><A href="http://www.ibm.com/developerworks/library/j-aopwork2/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AOP Tool comparison, Part 2: Development environments</A>（developerWorks,2005 年 2 月），在文中，作者重点介绍了与开发环境的工具集成和构建过程。<BR><BR>
<LI>请跳至第 2 部分，这一部分介绍 IDE 集成：<A href="http://www.ibm.com/developerworks/java/library/j-ajdt/index.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Develop aspect-oriented development with Eclipse and AJDT</A>（developerWorks，2004 年 9 月）。<BR><BR>
<LI>Eclipse.org 中包含关于 <A href="http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/aj5announce.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AspectJ and AspectWerkz joining forces</A> 的最新发布版本。<BR><BR>
<LI>请参阅 Eclipse Project，学习更多关于 <A href="http://eclipse.org/aspectj/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AspectJ</A> 的知识。<BR><BR>
<LI>Codehaus 中包含关于 <A href="http://aspectwerkz.codehaus.org/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">AspectWerkz</A> 的信息。<BR><BR>
<LI>要学习更多关于JBoss AOP 的内容，请参阅 <A href="http://www.jboss.org/products/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">JBoss</A>。<BR><BR>
<LI>Spring 框架的 Web 站点中包括关于 <A href="http://www.springframework.org/docs/reference/aop.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Spring AOP</A> 的信息。<BR><BR>
<LI>要学习更多 Java 平台上 AOP 的基础知识？请从 Nicholas Lesiecki 撰写的 <A href="http://www.ibm.com/developerworks/java/library/j-aspectj/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Improve modularity with aspect-oriented programming</A>（developerWorks，2002 年 1 月）开始。<BR><BR>
<LI>在 <A href="http://www.ibm.com/developerworks/rational/library/2782.html" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">A look at aspect-oriented programming</A>（<I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">The Rational Edge</I>，2004 年 1 月）中，Gary Pollice 用一个登录示例介绍了 AOP 的基本概念。<BR><BR>
<LI>本文中使用的 <CODE>Account</CODE> 示例最初出现在 Ramnivas Laddad 撰写的 <I xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><A href="http://devworks.krcinfo.com/WebForms/ProductDetails.aspx?ProductID=1930110936">AspectJ in Action</A></I>（Manning，2003 年）。<BR><BR>
<LI>表 1 中的用户基数调查是以最初显示在 <A href="http://www.aosd.net/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">aosd.net</A> 上的信息为基础，这些调查数据也是每年召开的 Aspect-Oriented Software Development 会议所使用数据的来源。<BR><BR>
<LI>在 <A href="http://www.ibm.com/developerworks/cn/java/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><I>developerWorks</I> Java 技术专区</A>可以找到数百篇有关 Java 各个方面的技术文章。<BR><BR>
<LI>请参阅 <A href="http://devworks.krcinfo.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Developer Bookstore</A>，以获得技术书籍的完整清单，其中包括数百本 <A href="http://devworks.krcinfo.com/WebForms/ProductList.aspx?search=FreeText&amp;SearchT=Keyword&amp;txtSearch=java" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">Java 相关主题</A>的书籍。<BR><BR>
<LI>还请参阅 Java 技术专区，从 developerWorks 那里获得侧重于 Java 的免费 <A href="http://www.ibm.com/developerWorks/cn/cnedu.nsf/java-onlinecourse-bytitle?OpenView&amp;Count=500" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">教程</A>的完整清单。<BR></LI></UL>
<P></P>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD><A name=author1></A><SPAN class=atitle2>关于作者</SPAN><BR>Mik Kersten 是一流的面向方面的编程专家，也是 AspectJ 和 AJDT eclipse.org 项目的参与者。作为 Xerox PARC 的研究科学家，他为 AspectJ 构建了 IDE 支持。他正在不列颠哥伦比亚大学攻读博士学位，他的主要工作是使 IDE 更加面向方面。他也向构建开发工具的公司提供咨询，帮助公司利用、支持面向方面的编程技术。</TD></TR></TBODY></TABLE><BR clear=all></TD></TR></TBODY></TABLE><img src ="http://www.blogjava.net/jinfeng_wang/aggbug/1989.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jinfeng_wang/" target="_blank">jinfeng_wang</a> 2005-03-13 16:18 <a href="http://www.blogjava.net/jinfeng_wang/archive/2005/03/13/1989.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>