| 网站首页 | 文章中心 | 电子书下载 | 矢量图库 | 视频教程 | 素材下载 | 程序代码下载 | JS代码 | 论坛 | 
常用软件类:
|杀毒安全 |联络聊天 |网络软件 |多媒体类 |系统工具 |图形图像 |系统工具 |应用软件 |行业软件
开发设计类:
|动画制作 |图像处理 |3D设计 |操作系统 |站长学院 |网络相关 |WEB设计 |数据库类 |程序开发
Java中实现基于Aspectwerkz的AOP开发
作者:佚名    文章来源:网络    点击数:    更新时间:2006-10-18
 

 
五、编译示例应用

  如果你想深入研究一下本文的示例应用,可以解开WAR文件提取它的内容。你会发现根目录下有一个aspectwerkz.xml文件,构造应用时它会被复制到WEB-INF/classes目录。Servlet和advice的源文件在WEB-INF/src目录下,另外还有一个构建这些类的ANT脚本。

  在运行这个示例程序之前,你还要对它进行后期编译。下面是具体的操作步骤:

  ⑴ 在命令行窗口中,转到解开WAR文件的目录。

  ⑵ 输入下面的命令调用AW编译器:aspectwerkz -offline aspectwerkz.xml WEB-INF/classes -cp %TOMCAT_HOME%\common\lib\servlet.jar。如后期编译顺利通过,应看到下面的输出:

( 1 s )
SUCCESS: WEB-INF\classes

  在构建文件中有一个名称为war的ANT任务,你可以用它重新创建WAR文件。

  六、运行示例应用

  首先启动(或重新启动)Tomcat,然后在浏览器中打开http://localhost:8080/demo/。

  页面打开后,可以看到一个带二个输入框的HTML表单,一个输入名字,一个输入邮件地址。输入一些数据,然后点击按钮提交表单,出现一个页面显示出联系人信息和一个指向联系人清单的链接。

  七、代码分析

  JSP页面就不分析了,现在我们对它不感兴趣。我们来看看AOPServlet的代码。

package example;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class AOPServlet extends HttpServlet {
 public void doGet(HttpServletRequest request, HttpServletResponse response)
 throws ServletException, IOException {
  Person person = new Person();
  if (request.getParameter("name") != null) {
   person.setName(
   request.getParameter("name"));
  }
  if (request.getParameter("email") != null) {
   person.setEmail(
   request.getParameter("email"));
  }
  request.setAttribute("person", person);
  RequestDispatcher rd =request.getRequestDispatcher("/view.jsp");
  rd.forward(request, response);
 }
}

  在这个例子中,Servlet的代码己尽量精简,只包含一些必不可少的代码,如创建了一个绑定请求参数的对象等,但没有持久化操作,不需要额外的imports,它只实现了作为Servlet必须实现的最基本的操作。

  然而,根据说明文档的要求,这个应用程序必须将所有Person类型的对象特久化,所以要为这个应用程序加入一个aspect。为创建这个aspect,我们首先要创建一个aspectwerkz.xml文件并将该文件放入classpath指定的目录。本文示例提供了一个简单的例子,你可以用编辑器打开查看。

  aspectwerkz.xml的第一部份定义了可用的advice,我们可以根据需要加入任意数量的advice:

<advice-def name="persist" class="example.PersistenceAdvice" deployment-model="perJVM"/>

  在这个片段中,我们定义了一个名称为persist的advice,它的类型是example.PersistenceAdvice。最后一个属性定义了该advice的排它性,在这里它的值是perJVM,表示在每一个JVM中只创建该advice的一个实例(有关部署模式的更多说明,请参见Aspectwerkz的文档。

  第二部份开始定义aspect,这里就是我们将advice映射到point-cut创建aspect的地方。

<aspect name="servlet">
<pointcut-def name="all" type="method"
pattern="* example.*Servlet.doGet(..)"/>
<bind-advice pointcut="all">
<advice-ref name="persist"/>
</bind-advice>
</aspect>

  下面我们一行一行地分析这段代码:

  ⑴ 我们创建了一个叫做servlet的aspect。如有必要,我们可以创建任意数量的aspect。

  ⑵ 在第二行,我们创建了一个叫做all的point-cut,它只适用于方法(type="method")。

  ⑶ 第三行我们用一个正则表达式规定了把advice应用到哪里。在这个例子中,我们指出应用advice的条件是:不管返回值的类型是什么(第一个“*”),名称以servlet结尾(*servlet)且包含一个带任意参数的doGet方法(doGet(..))的example包里面的类。

  ⑷ 在第四行,我们告诉Aspectwerkz编译器要把后面的advice应用到所有的point-cut。

  ⑸ 在这里我们声明要使用的advice是persist。

  现在我们知道了如何映射point-cut与advice创建出aspect,下面来看看一个提供advice的类的实例。在映射文件中,我们注册了一个example.PersistenceAdvice类型的advice,下面是该类型的源代码:

package example;

import javax.servlet.http.*;
import org.codehaus.aspectwerkz.advice.*;
import org.codehaus.aspectwerkz.joinpoint.*;

public class PersistenceAdvice extends AroundAdvice {
 public PersistenceAdvice() {
  super();
 }
 public Object execute(final JoinPoint joinPoint)
 throws Throwable {
  MethodJoinPoint jp =(MethodJoinPoint) joinPoint;
  final Object result = joinPoint.proceed();
  Object[] parameters = jp.getParameters();
  if (parameters[0] instanceof HttpServletRequest) {
   HttpServletRequest request =(HttpServletRequest) parameters[0];
   if (request.getAttribute("person") != null) {
    Person contact =(Person) request.getAttribute("person");
    ContactManager persistent = new ContactManager();
    String fileName =(request.getRealPath("/")+"contacts.txt");
    persistent.save(contact, fileName);
   }
  }
  return result;
 }
}

  execute()方法的第一行很容易理解,就是尽量把它定型成最具体的类型,第二行或许是最重要的:因为我们想要运行该方法并检查结果,所以必须调用proceed()。在下一部份,我们捕获HttpServletRequest,提取由Servlet放入的对象(记住,此时doGet()方法己运行结束)。

  最后,我们创建一个名称为ContactManager的类,它的功能是把Person的数据保存到一个文本文件。实际上,要把数据保存到XML文件、数据库或其它持久化存储机制也很方便。

  这里需要掌握的一点是,在设计应用或建立原型的阶段,Servlet并不知道未来会发生什么变化,第二阶段的功能可以随时加入,正因为如此,所以我们说应用程序能够在发展过程中学习新的能力,以后要添加新的功能非常方便。

  【结束语】 我们在前面的例子中试验了一个简单的应用,将它部署到Tomcat,并用浏览器运行和测试它的功能。虽然这个应用本身并无任何实际用途,但它示范和证实了一些非常有用的概念。想象一下,你将可以快速地建立原型,完成后再引入安全、日志、持久化、缓冲之类的Cross-cutting concern。不管原始应用的规模有多大,你将能够在十分钟之内轻松地为整个应用加入日志功能!

  希望你能够超越本文的简单例子,去看看如何在自己的项目中采用AOP技术。熟悉AOP的概念当然需要一定的时间,但肯定会得到回报,对于一个中等规模的项目,它会让你省下数星期时间,或者少写数千行重复的代码。

上一页  [1] [2] 


相关文章