您的位置:首页 > 编程语言

面向方面编程慨述和JBoss(2)

2006-12-23 22:15 204 查看
例子1、使用监听器

  JBoss 4.0带有一个面向方面的程序设计框架。这个框架和JBoss应用程序服务器紧密地整合,但是你还可以在你自己的应用程序上单独运行它。你只有看到它如何工作,才能真正明白一个概念,所以让我们使用JBoss AOP中的例子来说明所有这些东西是如何合作的。在本文剩余的部分,我们将使用AOP构建一个简单的追踪框架。

  定义一个监听器

  首先要做的是实现我们的小跟踪框架,来定义将做实际工作的监听器。 JBoss AOP中的所有的监听器必须实现org.jboss.aop.Interceptor接口。

public interface Interceptor
{
public String getName();
public InvocationResponse invoke(Invocation invocation) throws Throwable;
}
  JBoss AOP中被监听的所有字段、构造器和方法被转化为一个普通的Invocation调用。方法参数被装入一个Invocation对象,然后一个方法、字段访问或者构造器的返回值被装入一个InvocationResponse对象。Invocation对象还驱动监听器链。为了解释清楚,我们来看看在一个例程中所有这些对象如何使用。

import org.jboss.aop.*;
import java.lang.reflect.*;

public class TracingInterceptor implements Interceptor
{
public String getName() { return TracingInterceptor; }
public InvocationResponse invoke(Invocation invocation)
throws Throwable
{
String message = null;

if (invocation.getType() == InvocationType.METHOD)
{
Method method = MethodInvocation.getMethod(invocation);
message = method: + method.getName();
}
else if (invocation.getType() == InvocationType.CONSTRUCTOR)
{
Constructor c = ConstructorInvocation.getConstructor(invocation);
message = constructor: + c.toString();
}
else
{
// Do nothing for fields. Just too verbose.
return invocation.invokeNext();
}

System.out.println(Entering + message);

// Continue on. Invoke the real method or constructor.
InvocationResponse rsp = invocation.invokeNext();
System.out.println(Leaving + message);
return rsp;
}
}
  上面的监听器将监听一个字段、构造器或者方法的所有调用。如果调用类型是一个方法或者构造器,那么带有方法或者构造器签名的跟踪信息将被输出到控制台。

  附加一个监听器

  好的,这样我们就已经定义好监听器了。但是我们如何把这个监听器附加到一个实际的类中呢?为了实现这个目的,我们需要定义一个切入点(pointcut)。对于JBoss AOP来说,切入点在一个XML文件中被定义。让我们来看看它看起来是什么样的。

<?xml version="1.0" encoding="UTF-8">
<aop>
<interceptor-pointcut class="POJO">
<interceptors>
<interceptor class="TracingInterceptor" />
</interceptors>
</interceptor-pointcut>
</aop>
  上面的切入点把TracingInterceptor附加到一个名为POJO的类中。这似乎有点麻烦;我们必须为我们想跟踪的每个类创建一个切入点吗?幸运的是,监听器-切入点的类属性可以使用任何正则表达式。因此,如果你想追踪每个JVM加载的类,类的表达式将变为 .*。 如果你只想追踪某个特定的包,那么表达式将是com.acme.mypackge.*。

  当独立运行JBoss AOP时,任何适合META-INF/jboss-aop.xml模式的XML文件都将在JBoss AOP运行时间载入。如果相对路径被包含在任何JAR中或者目录被包含在你的CLASSPATH中,特定的XML文件将在启动时被JBoss AOP运行时间载入。

  运行例程

  我们将使用上面定义的切入点运行这个例程。POJO类如下。

public class POJO
{
public POJO() {}
public void helloWorld() { System.out.println(Hello World!); }
public static void main(String[] args)
{
POJO pojo = new POJO();
pojo.helloWorld();
}
}
TracingInterceptor将监听main ()、POJO ()和helloWorld ()的调用。输入为:
Entering method: main
Entering constructor: public POJO()
Leaving constructor: public POJO()
Entering method: helloWorld
Hello World!
Leaving method: helloWorld
Leaving method: main
  你可以到http://www.jboss.org/index.html?module=html&op=userdisplay&id=developers/projects/jboss/aop去下载JBoss AOP和例程代码。 编译和执行:

$ cd oreilly-aop/example1
$ export CLASSPATH=.;jboss-common.jar;jboss-aop.jar;javassist.jar
$ javac *.java
$ java -Djava.system.class.loader=org.jboss.aop.standalone.SystemClassLoader POJO
  JBoss AOP操作字节码,附加到监听器上。因为没有编译步骤,AOP运行时间必须全局控制ClassLoader。所以如果你在JBoss应用程序服务器以外运行的时候,你必须使用一个JBoss指定的classloader覆盖系统classloader。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: