服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

面向方面编程aop和jboss(二)


  访问metadata
  为了用元数据,它在运行时间必须是可达的。类的元数据是通过invocation对象可达的。为了在我们的例子使用它,tracinginterceptor必须要修改一点点。
  
  public class tracinginterceptor implements interceptor
  {
    public string getname() { return tracinginterceptor; }
    public invocationresponse invoke(invocation invocation)
      throws throwable
    {
     string filter = (string)invocation.getmetadata(tracing, filter);
     if (filter != null && filter.equals(true))
    return invocation.invokenext();
  
     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;
    }
  }
  
  运行例子2
  [code]pojo类将扩展一点,增加get()和set()方法。
  public class pojo
  {
    public pojo() {}
    public void helloworld() { system.out.println(hello world!); }
  
    private int counter = 0;
  
    public int getcounter() { return counter; }
    public void setcounter(int val) { counter = val; }
    public static void main(string[] args)
    {
     pojo pojo = new pojo();
     pojo.helloworld();
     pojo.setcounter(32);
     system.out.println(counter is: + pojo.getcounter());
    }
  }
  tracinginterceptor将拦截对main(),pojo()和helloworld()调用。输出应该看起来如下:
  entering constructor: public pojo()
  leaving constructor: public pojo()
  entering method: helloworld
  hello world!
  leaving method: helloworld
  [/code]
  
  你能够在这里下载jboss aop和离子代码。编译和执行:
  $ cd oreilly-aop/example2
  $ export classpath=.;jboss-common.jar;jboss-aop.jar;javassist.jar
  $ javac *.java
  $ java -djava.system.class.loader=org.jboss.aop.standalone.systemclassloader pojo
  
  例子3.使用导言
  如果我们能够为特定的实例关闭和打开,那将很酷。jboss aop有一个api,他绑定元数据到一个对象实例,但是让我们伪装一个实际的跟踪api是一个更好的方案。在这例子中,我们通过用一个导言,将改变pojo类的本身的定义。我们将强制pojo类去实现一个跟踪借口和提供混合类,这个混合类处理新的跟踪api。这将是跟踪借口:
  
  public interface tracing
  {
    public void enabletracing();
    public void disabletracing();
  }
  
  定义一个混合的类
  tracing接口将在混合类中实现。当一个pojo是实例时,一个混合对象混合类将绑定到pojo类。下面是实现:
  
  import org.jboss.aop.advised;
  
  public class tracingmixin implements tracing
  {
    advised advised;
  
    public tracingmixin(object obj)
    {
     this.advised = (advised)obj;
    }
  
    public void enabletracing()
    {
     advised._getinstanceadvisor().getmetadata().addmetadata(
    "tracing", "filter", true);
    }
  
    public void disabletracing()
    {
     advised._getinstanceadvisor().getmetadata().addmetadata(
    "tracing", "filter", false);
    }
  }
  
  enabletracing()方法绑定filter属性到对象实例。在disabletracing()方法作同样的事,但是制定filter属性为false。这两个方法是元数据能够怎么样用于超过一个类级别。元数据也能够实例级的应用。元数据应用在实例级别。
  
  绑定一个导言
  好了,所以我们定义跟踪接口,并且实现这个混合类。下一步是应用导言到pojo类。像拦截器,我们必须在xml中定义一个ponitcut。让我们看一下这项什么。
  
  <?xml version="1.0" encoding="utf-8">
  <aop>
    <introduction-pointcut class="pojo">
     <mixin>
       <interfaces>tracing</interfaces>
       <class>tracingmixin</class>
       <construction>new tracingmixin(this)</construction>
     </mixin>
    </introduction-pointcut>
  </aop>
  
  上面的pointcuts将强制pojo类实现tracing接口。现在,当一个pojo实例被初始化,一个tracingmixin也将被实例化。tracingmixin被初始化的途径被定义在<contstruction>标签中。你能够把想要的任一行java代码放入在<contstruction>标签中。
  
  运行例子3
  pojo类为了显示tracingapi怎么被访问,它已经被扩展了一点。tracinginterceptor仍然和例子2一样。
  
  [code]public class pojo
  {
    public pojo() {}
    public void helloworld() { system.out.println(hello world!); }
  
    public static void main(string[] args)
    {
     pojo pojo   = new pojo();
     tracing trace = (tracing)this;
     pojo.helloworld();
  
     system.out.println("turn off tracing.");
  
     trace.disabletracing();
     pojo.helloworld();
  
     system.out.println("turn on tracing.");
  
     trace.enabletracing();
     pojo.helloworld();
    }
  }
  [/code]
  注意我们转换pojo到tracing接口。输出应该看起来这样:
  
  entering constructor: pojo()
  leaving constructor: pojo()
  entering method: helloworld
  hello world!
  leaving method: helloworld
  turn off tracing.
  entering method: disabletracing
  leaving method: disabletracing
  hello world!
  turn on tracing.
  entering method: helloworld
  hello world!
  leaving method: helloworld
  
  注意被增加到tracinginterceptor 中的interceptor-pointcut也应用到那些通过tracing 导言导入的方法中。
  为了编译和运行这个例子:
  
  $ cd oreilly-aop/example3
  $ export classpath=.;jboss-common.jar;jboss-aop.jar;javassist.jar
  $ javac *.java
  $ java -djava.system.class.loader=org.jboss.aop.standalone.systemclassloader pojo
  
  结论
  面向方面编程对于软件开发是一个强有力的新工具。为了使你的软件开发过程更加动态和流畅,用jboss4.0,你能够实现你自己的拦截器,元数据和导言。更详细的文档参见我们的站点www.jboss.org。那会有一些惊奇等着你,象我们已经在我们新的框架上实现了一套服务。拥有它并恰当的使用。

扫描关注微信公众号