术语
Joinpoint:joinpoint是java程序中的任何点,例如方法调用,构造器访问一个域的执行等。也可以将它看作这是java事件。例如方法调用、构造器调用和数据域访问。
Invocation:一个Invocation是一个Jboss AOP类,它封装了在运行时间是什么Joinpoint。它包含了诸如哪个方法被调用,方法的参数等信息。
Advice:advice就是一个当一个特殊的Joinpoint被执行时,被调用的方法。也可以把它当成一段拦截的代码,或者advice是“事件处理器”。
Pointcut:Pointcuts是AOP的表达式语言。就像正则表达式匹配字符串。一个pointcut匹配一个特定的Jointpoint。
Introduction:修改Java类结构和类型的指令。用于强制已存在的类实现一个接口或添加annotation。
Aspect:aspect是纯Java类,封装了多个advice,pointcut。
Interceptor:interceptor是aspect和一个名称为"invoke"的advice的组合。它是一个特定的接口,使得你的代码通过强制实现一个接口被检查,也可以在Jmx Mbeans中复用。
Aspect的实现
JBoss AOP是纯Java框架。所有AOP结构是以纯Java类定义,且以Xml方式绑定到application或annotation。
Invocation对象
Invocation对象是joinpoint运行时的封装。它们包含了joinpoint(参数,java.lang.reflect.*,等),且也驱动aspect流程。
org.jboss.aop.joinpoint.MethodInvocation:方法执行。当方法被解释执行时,被创建和使用
org.jboss.aop.joinpoint.ConstructorInvocation:构造器执行。当构造器被解释执行时,被创建和使用。
org.jboss.aop.joinpoint.FieldInvocation:数据域执行,抽象基础类,封装数据域访问。
org.jboss.aop.joinpoint.FieldReadInvocation:Field读取访问。FieldInvocation子类
org.jboss.aop.joinpoint.FieldWriteInvocation:数据域修改,FieldInvocation子类
org.jboss.aop.joinpoint.MethodCalledByMethod:调用者pointcuts,当使用"call"pointcut表达式时,这个invocation对象被分配。该特殊类封装了一个方法:调用其他方法,所以你可以访问调用者和被调用者。
org.jboss.aop.joinpoint.MethodCalledByConstructor:调用者pointcut。当使用"call"pointcut表达式时,这个invocation对象被分配。它封装了一个构造器:调用其他方法,所以你可以访问调用者和被调用者。
org.jboss.aop.joinpoint.ConstructorCalledByMethod:调用者pointcut。当使用"call"pointcut表达式时,这个invocation对象被分配。它封装了一个方法:调用构造器,所以你可以访问调用者和被调用者。
org.jboss.aop.joinpoint.ConstructorCalledByConstructor:调用者pointcut。当使用"call"pointcut表达式时,这个invocation对象被分配。它封装了一个构造器:调用它构造器,所以你可以访问调用者和被调用者。
Aspect类
Aspect是纯Java类,定义了0或多个advince,pointcut或混合。
public class Aspect
{
public Object trace(Invocation invocation) throws Throwable {
try {
System.out.println("Entering anything");
return invocation.invokeNext(); // proceed to next advice or actual call
} finally {
System.out.println("Leaving anything");
}
}
}
本例子中的advice trace跟踪了任何joinpoint类型,注意invocation.invokeNext()用来驱动advice链。它要么调用chain中的下一个advice,要么是真实的方法或构造器调用。
Advice Methods
为了基本的拦截,所有的方法都遵循一下形式:Object methodName(Invocation object) throws Throwable
Invocation.invokeNext()方法必须被advice代码或其他advice调用,真实的方法,field,构造器invocation不会发生。、
通过不同的invocation类型,方法名可以重载。例如:
public class Aspect{
public Object trace(MethodInvocation invocation)throws Trowable{
try{
System.out.println("enter method:"+invocation.getMethod())
return invocation.invokeNext();
}finally{
System.out.println("leaving method:"+invocation.getMethod())
}
}
public Object trace(ConstructorInvocation invocation)throws throwable{
try{
System.out.println("enter method:"+invocation.getConstructor())
return invocation.invokeNext();
}finally{
System.out.println("leaving method:"+invocation.getConstructor())
}
}
}
JBOSS AOP提供了五种advice:before,around,after,finally和after-throwing。
Interceptor
Interceptors是aspect的一个特殊类型,它仅包含一个advice,次advice有被接口org.jboss.aop.advice.Interceptor定义的签名:
public interface Interceptor
{
public String getName();
public Object invoke(Invocation invocation) throws Throwable;
}
方法invoke(Invocation)是Interceptor中唯一的advice。getName()在Jboss AOP框架中用来做标识。所以次方法必须返回一个在整个系统中唯一的名称。它仅用来为aspect添加InstanceAdvisor。
Dynamic CFlow
Dynamic CFlow允许你定义代码。Dynamic CFlow必须为true时触发在cflow测试上的正值。测试在运行时动态发生,且当与pointcut表达式绑定时允许你做运行是检测绑定的advice是否运行。
public interface DynamicCFlow
{
boolean shouldExecute(Invocation invocation);
}