访问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。那会有一些惊奇等着你,象我们已经在我们新的框架上实现了一套服务。拥有它并恰当的使用。
闽公网安备 35060202000074号