信息化 频道

两次飞跃创辉煌

    定义一个拦截器

    为了实现我们对于框架的跟踪,我们必须作的第一件事是定义一个拦截器,它将作实际的工作。在JBOSS AOP中,所有的拦截器必须实现org.jboss.aop.Interceptor 接口。
public interface Interceptor {      public String getName();      public InvocationResponse invoke(Invocation invocation) throws Throwable;    }
    在JBoss AOP中,被拦截的所有域,构造器和方法被转成一般的invoke调用。方法的参数被填入一个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, pointcuts 是在一个XML文件中定义的。让我们看一下这看起来象什么。
  
    上面的pointcut绑定TracingInterceptor到一个叫做POJO的类。这看起来有一点麻烦;我们不得不为每一个想跟踪的类创建一个 pointcut吗?幸运的是,interceptor-pointcut的类属性可以用任何的正规表达式。所以如果你想跟踪由JVM载入的类,类表达式将变为 .*。如果你仅仅想跟踪一个特定的包,那么表达式将是com.acme.mypackge.*。

    当单独运行JBoss AOP时,任何符合 META-INF/jboss-aop.xml模式的XML文件将被JBoss AOP 运行时间所载入。如果相关的路径被包含在任何JAR或你的CLASSPATH的目录中,那个特定的XML文件将在启动时,由JBoss AOP 运行时间所载入。
  
    运行这个例子,我们将用上面定义的pointcut去运行例子。POJO类看起来如下:
[code]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();     }   }   [/code]   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
    你能够在这里下载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制定的一个类载入器覆盖系统的类载入器。

    TraceingInterceptor不跟踪域访问,因为它有一点繁琐。对于开发者,实现get()和set()方法去封装域访问是一个一般的实践。如果TracingInterceptor能够过滤出,并且不跟踪这些方法,那是非常好的。这个例子显示你能够用JBoss AOP 元数据去实现基于任一方法的过滤。一般,元数据用于更复杂的事情,如定义事务属性,每个方法的安全角色或者持久性映射,但是这个例子应该足够说明元数据能够怎样用在 AOP使能的应用中。
0
相关文章