例2、使用元数据
TracingInterceptor不追踪字段访问,因为它有点太冗长。对于开发者来说,实现get()和set()方法来封装字段访问是一个惯例。如果TracingInterceptor可以过滤而不是跟踪这些方法,那将非常好。 这个例子向你说明,如何使用JBoss AOP元数据来实现基于一个每方法结构的过滤。通常,元数据被用于更复杂的,如定义事务属性、每方法安全角色或者持久映射,但是这个例子将足以说明元数据如何被用于一个能使用AOP的应用程序。
定义类元数据
为了添加这个过滤功能,我们将提供了一个标志,你可以使用它来关闭跟踪。 我们将回到我们的AOP XML文件,来定义将删除对get()和set()方法的跟踪的标记。 实际上,跟踪main()函数也有点意义不大,所以让我们也把这个跟踪给过滤掉。
上面的XML定义一组名为tracing的属性。 过滤属性将被附加到每个以get或set开头的方法。 正则表达式格式使用JDK 1.4定义的表达式。 这个元数据可以在TracingInterceptor里通过Invocation对象访问。
访问元数据
对于有用的元数据,它必须在运行时间可访问。 类元数据可以通过Invocation对象访问。 为了在我们的例子中使用它,必须稍微修改一下TracingInterceptor。
运行例 2
POJO类已经做了一些扩展,添加了get()和set()方法。
TracingInterceptor将监听main()、POJO()和helloWorld()的调用。输出为:
你可以在下面的网址下载JBoss AOP和示例代码:
(http://www.jboss.org/index.html?module=html&op=userdisplay&id=developers/projects/jboss/aop)。
编译和执行:
TracingInterceptor不追踪字段访问,因为它有点太冗长。对于开发者来说,实现get()和set()方法来封装字段访问是一个惯例。如果TracingInterceptor可以过滤而不是跟踪这些方法,那将非常好。 这个例子向你说明,如何使用JBoss AOP元数据来实现基于一个每方法结构的过滤。通常,元数据被用于更复杂的,如定义事务属性、每方法安全角色或者持久映射,但是这个例子将足以说明元数据如何被用于一个能使用AOP的应用程序。
定义类元数据
为了添加这个过滤功能,我们将提供了一个标志,你可以使用它来关闭跟踪。 我们将回到我们的AOP XML文件,来定义将删除对get()和set()方法的跟踪的标记。 实际上,跟踪main()函数也有点意义不大,所以让我们也把这个跟踪给过滤掉。
| <?xml version="1.0" encoding="UTF-8"> <aop> <class-metadata group="tracing" class="POJO"> <method name="(get.*)|(set.*)"> <filter>true</filter> </method> <method name="main"> <filter>true</filter> </method> </class-metadata> </aop> |
上面的XML定义一组名为tracing的属性。 过滤属性将被附加到每个以get或set开头的方法。 正则表达式格式使用JDK 1.4定义的表达式。 这个元数据可以在TracingInterceptor里通过Invocation对象访问。
访问元数据
对于有用的元数据,它必须在运行时间可访问。 类元数据可以通过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
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 |
你可以在下面的网址下载JBoss AOP和示例代码:
(http://www.jboss.org/index.html?module=html&op=userdisplay&id=developers/projects/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 |
浙公网安备 33010602011771号