专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »Java教程 » javaaop:Java中实现基于Aspectwerkz的AOP开发 »正文

javaaop:Java中实现基于Aspectwerkz的AOP开发

来源: 发布时间:星期五, 2008年12月19日 浏览:2次 评论:0
、AOP编程概览   面向对象编程技术进入软件Software开发主流对软件Software开发方式产生了极大影响开发者可以用组实体以及这些实体的间关系将系统形象地表示出来这使得他们能够设计出规模更大、更复杂系统开发周期也比以前更短OO开发问题是它本质上是静态需求细微变化就可能对开发进度造成重大影响   Aspect-Oriented Programming(AOP)是对OO技术补充和完善它允许开发者动态地修改静态OO模型构造出个能够不断增长以满足新增需求系统就象现实世界中对象会在其生命周期中不断改变自身应用也可以在发展中拥有新功能   例如许多人想必有过在开发简单Web应用时将Servlet作为入口点经验即用Servlet接收HTML表单输入经过处理后返回给用户开始时Servlet可能是非常简单只有刚好满足用户需求最少量代码然而随着“第 2需求”实现例如实现异常处理、安全、日志等功能代码体积就会增加到原来 3、 4倍——的所以称的为“第 2需求”Servlet基本功能是接受和处理用户请求对于这个目标来说日志、安全的类机制并不是必不可少   AOP允许动态地改变OO静态模型不必修改原来静态模型也可以加入满足第 2需求所需代码(实际上甚至连原来源代码也不需要)更令人称奇后来加入代码往往可以集中在个地方而不必象单纯使用OO时那样将后来加入代码分散到整个模型    2、基本术语   在介绍AOP开发例子的前我们先来了解几个标准AOP术语以便更好地掌握相关概念   █ Cross-cutting concern   在OO模型中虽然大部份类只有单、特定功能但它们通常会和其他类有着共同第 2需求例如当线程进入或离开某个思路方法时我们可能既要在数据访问层类中记录日志又要在UI层类中记录日志虽然每个类基本功能极然区别但用来满足第 2需求代码却基本相同   █ Advice   它是指想要应用到现有模型附加代码在本例中它是指线程进入或退出某个思路方法时要运行日志代码   █ Po-cut   这个术语是指应用个执行点在这个执行点上需要采用前面cross-cutting concern在本例中当线程进入个思路方法时出现个Po-cut当线程离开思路方法时又出现另个Po-cut   █ Aspect   Po-cut和advice结合在起就叫做aspect在下面例子中我们通过定义个po-cut并给予适当advice加入了个日志(logging)aspect   AOP还有其它许多特性和术语例如引入(Introduction)即把接口/思路方法/域引入到现有类——它极大地拓宽了开发者想象力不过本文只介绍些最基本持性熟悉这里介绍概念后你再深入步研究AOP其它特性看看如何在自己开发环境中使用它们    3、现有框架   目前最成熟、功能最丰富AOP框架当数AspectJAspectJ已成为大多数其它框架跟从标准但是AspectJ也走出了非同寻常实现为Java语言增添了新关键词虽然新语法并不难学但却意味着我们必须换个编译器还要重新配制编辑器只有这样才能适应新语法在规模较大开发组中这些要求可能难以办到整个开发小组都会受到影响由于语言本身变化开发小组把AOP技术引入到现有项目学习周期随的延长   现在我们需要是这样个框架它可以方便地引入且不会对原来开发和构造过程产生任何影响满足这些要求框架不止例如JBoss AOP、Nanning、Aspectwerkz(AW)本文选用是Aspectwerkz它可能是最容易学习框架也是最容易集成到现有项目框架   Aspectwerkz由Jonas Boner和Alexandre Vasseur创建它是目前最快速、功能最丰富框架的虽然它还缺乏AspectJ某些功能但己足以满足大多数开发者在许多情形下需要   Aspectwerkz最令人感兴趣特性的是它能够以两种区别模式运行:联机模式和脱机模式在联机模式下AW直接干预属于JVM底层类装入机制截取所有类装入请求对字节码实施即时转换AW提供了干预类装入过程许多选项另外还有个替代bin/java命令封装脚本这个脚本能够根据Java版本和JVM能力自动生成组可运行配制对于开发者联机模式有许多优点它能插入到任何类装入器并在类装入期间生成新也就是说我们不必手工修改应用只要按通常方式部署即可不过联机模式要求对应用服务器进行额外配制有时这要求可能很难满足   在脱机模式下生成类需要 2个步骤步是用标准编译器编译第 2步是重点——以脱机模式运行AWcompiler编译器让它处理新生成编译器将修改这些类字节码根据个XML文件定义在适当po-cut插入advice脱机模式优点是AWcompiler生成类能够在任何JVM 1.3以上虚拟机运行本文下面要用就是这种模式它不需要对Tomcat作任何修改只要对构造过程稍作修改就可以照搬到大多数现有项目    4、安装   本文将以个简单Web应用为例它用Ant编译部署在Tomcat 4+ Servlet容器上下面我们假定读者己准备好上述环境包括JVM 1.3+同时Tomcat被设置成从webapps文件夹自动部署应用自动将WAR扩展到目录(这是Tomcat默认操作方式因此只要你尚未修改Tomcat运行方式下面范例可直接运行)我们将把Tomcat安装位置称为%TOMCAT_HOME%   ⑴ 从http://apectwerkz.codehaus.org/下载Aspectwerkz解开压缩到适当位置我们将把这个位置称为%ASPECTWERKZ_HOME%   ⑵ 设置%ASPECTWERKZ_HOME%环境变量   ⑶ 将Aspectwerkz加入到PATH环境变量即设置 PATH=%PATH%;%ASPECTWERKZ_HOME%\bin\aspectwerkz   ⑷ 下载本文示范将它放入%TOMCAT_HOME%\webapps文件夹   ⑸ 将Aspectwerkz运行时类加入到Tomcatpath你可以将它JAR文件放入举例应用WEB-INF\lib文件夹或放入%TOMCAT_HOME%\common\lib 5、编译举例应用   如果你想深入研究下本文举例应用可以解开WAR文件提取它内容你会发现根目录下有个aspectwerkz.xml文件构造应用时它会被复制到WEB-INF/es目录Servlet和advice源文件在WEB-INF/src目录下另外还有个构建这些类ANT脚本   在运行这个举例的前你还要对它进行后期编译下面是具体操作步骤:   ⑴ 在命令行窗口中转到解开WAR文件目录   ⑵ 输入下面命令AW编译器:aspectwerkz -offline aspectwerkz.xml WEB-INF/es -cp %TOMCAT_HOME%\common\lib\servlet.jar如后期编译顺利通过应看到下面输出: ( 1 s ) SUCCESS: WEB-INF\es   在构建文件中有个名称为warANT任务你可以用它重新创建WAR文件    6、运行举例应用   首先启动(或重新启动)Tomcat然后在浏览器中打开http://localhost:8080/demo/   页面打开后可以看到个带 2个输入框HTML表单个输入名字个输入邮件地址输入些数据然后点击按钮提交表单出现个页面显示出联系人信息和个指向联系人清单链接    7、代码分析   JSP页面就不分析了现在我们对它不感兴趣我们来看看AOPServlet代码 package example; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public AOPServlet extends HttpServlet {  public void doGet(HttpServletRequest request, HttpServletResponse response)  throws ServletException, IOException {   Person person = Person;    (request.getParameter("name") != null) {    person.Name(    request.getParameter("name"));   }    (request.getParameter("email") != null) {    person.Email(    request.getParameter("email"));   }   request.Attribute("person", person);   RequestDispatcher rd =request.getRequestDispatcher("/view.jsp");   rd.forward(request, response);  } }   在这个例子中Servlet代码己尽量精简只包含些必不可少代码如创建了个绑定请求参数对象等但没有持久化操作不需要额外imports它只实现了作为Servlet必须实现最基本操作   然而根据介绍说明文档要求这个应用必须将所有Person类型对象特久化所以要为这个应用加入个aspect为创建这个aspect我们首先要创建个aspectwerkz.xml文件并将该文件放入path指定目录本文举例提供了个简单例子你可以用编辑器打开查看   aspectwerkz.xml部份定义了可用advice我们可以根据需要加入任意数量advice: <advice-def name="persist" ="example.PersistenceAdvice" deployment-model="perJVM"/>   在这个片段中我们定义了个名称为persistadvice类型是example.PersistenceAdvice最后个属性定义了该advice排它性在这里它值是perJVM表示在每个JVM中只创建该advice个例子(有关部署模式更多介绍说明请参见Aspectwerkz文档   第 2部份开始定义aspect这里就是我们将advice映射到po-cut创建aspect地方 <aspect name="servlet"> <pocut-def name="all" type="method" pattern="* example.*Servlet.doGet(..)"/> <bind-advice pocut="all"> <advice-ref name="persist"/> </bind-advice> </aspect>   下面我们行地分析这段代码:   ⑴ 我们创建了个叫做servletaspect如有必要我们可以创建任意数量aspect   ⑵ 在第 2行我们创建了个叫做allpo-cut它只适用于思路方法(type="method")   ⑶ 第 3行我们用个正则表达式规定了把advice应用到哪里在这个例子中我们指出应用advice条件是:不管返回值类型是什么(第个“*”)名称以servlet结尾(*servlet)且包含个带任意参数doGet思路方法(doGet(..))example包里面   ⑷ 在第 4行我们告诉Aspectwerkz编译器要把后面advice应用到所有po-cut   ⑸ 在这里我们声明要使用advice是persist   现在我们知道了如何映射po-cut和advice创建出aspect下面来看看个提供advice例子在映射文件中我们注册了个example.PersistenceAdvice类型advice下面是该类型源代码: package example; import javax.servlet.http.*; import org.codehaus.aspectwerkz.advice.*; import org.codehaus.aspectwerkz.joinpo.*; public PersistenceAdvice extends AroundAdvice {  public PersistenceAdvice {   super;  }  public Object execute(final JoinPo joinPo)  throws Throwable {   MethodJoinPo jp =(MethodJoinPo) joinPo;   final Object result = joinPo.proceed;   Object parameters = jp.getParameters;    (parameters[0] instanceof HttpServletRequest) {    HttpServletRequest request =(HttpServletRequest) parameters[0];     (request.getAttribute("person") != null) {     Person contact =(Person) request.getAttribute("person");     ContactManager persistent = ContactManager;     String fileName =(request.getRealPath("/")+"contacts.txt");     persistent.save(contact, fileName);    }   }    result;  } }   execute思路方法行很容易理解就是尽量把它定型成最具体类型第 2行或许是最重要:我们想要运行该思路方法并检查结果所以必须proceed在下部份我们捕获HttpServletRequest提取由Servlet放入对象(记住此时doGet()思路方法己运行结束)   最后我们创建个名称为ContactManager功能是把Person数据保存到个文本文件实际上要把数据保存到XML文件、数据库或其它持久化存储机制也很方便   这里需要掌握点是在设计应用或建立原型阶段Servlet并不知道未来会发生什么变化第 2阶段功能可以随时加入如此所以我们说应用能够在发展过程中学习新能力以后要添加新功能非常方便   【结束语】 我们在前面例子中试验了个简单应用将它部署到Tomcat并用浏览器运行和测试它功能虽然这个应用本身并无任何实际用途但它示范和证实了些非常有用概念想象你将可以快速地建立原型完成后再引入安全、日志、持久化、缓冲的类Cross-cutting concern不管原始应用规模有多大你将能够在十分钟的内轻松地为整个应用加入日志功能!   希望你能够超越本文简单例子去看看如何在自己项目中采用AOP技术熟悉AOP概念当然需要时间但肯定会得到回报对于个中等规模项目它会让你省下数星期时间或者少写数千行重复代码

相关文章

读者评论

  • 共0条 分0页

发表评论

  • 昵称:
  • 内容: