动态横切指的是在一个程序的执行时插入一段新的行为。在AspectJ中发生的横切大都是动态的。
静态横切(Static Crosscutting)
静态横切指的是对程序的静态结构进行修正的行为——如系统的类、接口、方面等。它不能更改系统的执行动作。
横切元素
连接点(Join Point)
连接点是一个应用程序执行中的一个标识点。它能够是一个方法的调用或一个类的数据成员的分配。如:
public class Account {
...
void credit(float amount) {
_balance += amount;
}
}
在account类中的连接点包括credit方法的执行以及_balance实例成员的访问。
切点(Pointcut)
切点是一个选择了一些连接点以及这些连接点上下文集合的程序结构。如我们捕捉Account类中的credit方法的执行:
execution(void credit(float))
通知(Advice)
通知就是被一个切点所选择的连接点所要执行的代码。通知能够在连接点的前(before)、后(after)、周围(around)执行。周围通知能够在连接点处改变代码的执行,它能替换这段代码或者绕过这段代码。通知类似一个方法。利用前面的切点,我们能够在Account类的credit方法执行前打印一条信息:
before() : executiong(void credit(float)) {
System.out.println("About to perform credit operation");
}
切点和通知一起就组成了一个动态横切。
引导(Introduction)
引导一个静态横切的指令,它为系统的类、接口、方面引进了一些更改。它为一些模块进行静态的更改,而不会影响它们的动作。例如你可以为一个类增加一个方法或字段。
declare parents : Account implements BankingEntity;
编译时申明(Compile-time declaration)
编译时申明是一个静态横切指令,它允许在你指定的某些确定场合下增加你想要的警告和错误通知。如:
declare warning : call(void Persistence.save(Object))
: "Consider using Persistence.saveOptimized()";
方面(Aspect)
方面是AspectJ中的核心单元,如同类在Java中的地位一样。它包含了为静态横切和动态横切所需要的表达式。切点、通知、引导、申明以及它们的组合都能被包含在方面中。在方面中还可以包含数据、方法和嵌套的类成员,就像一个普通的Java类。如:
public aspect ExampleAspect {
before() : execution(void Account.credit(float)) {
System.out.println("About to perform credit operation");
}
declare parents: Account implements BankingEntity;
declare warning : call(void Persistence.save(Object)) : "Consider using Persistence.saveOptimized()";
}