【IT168 技术文档】让我好好想想, AspectJ 中最常用的切入点是什么?哦,也许是 call ( Method-Signature )吧。这是个相对简单的方法签名。实际上,方法签名的完整形式如下:
[modifiers] [returnTypePattern] [DeclaredTypePattern.]methodName([Parameters])[throws TypePattern] ,其中方括号中的签名组件是可选的。 modifiers 为修饰符模式, returnTypePattern 为返回类型模式, DeclaredTypePattern 为类型声明模式, methodName 为方法名称, Parameters 为方法参数, throws TypePattern 为 throw 字句。该文仅仅介绍 DeclaredTypePattern ,因为相比之下其它模式比较简单的多。
在介绍类型声明模式之前,介绍一下类型模式。类型模式是匹配一种类型或一系列类型的方法。精确的类型模式是如 java.lang.String 一样的完整的有效类型名。但在使用 AspectJ 类型模式时,经常会用到下列通配符(这些通配符同样适用于 Spring 的 AOP )。
1 )“ *” :代表任意字符的零次或多次出现。当嵌入到一串字符的内部时,它匹配任意字符的零次或多次出现,除了包分割符( . )。
2 )“ +” :用作类型模式的后缀,代表此类型和其所有的子类型(那些扩展或实现带后缀类型的类型)。
3 )“ ..” :用于指定所有的子包,它匹配任意以包分割符开头和结束的字符串。
1 ) *Account 使用 Account 名称结束的类型,如 CheckingAccount
2 ) java.*.Date 类型 Date 在任何直接的 java 子包中,如 java.util.Date 和 java.sql.Date
3 ) java..* 任何在 java 包或者所有子包中的类型,如 java.awt 或者 java.awt.event
4 ) javax..*Model+ 所有 javax 包或者子包中以 Model 结尾的类型和其所有子类,如 TableModel,TreeModel 。
现在开始说说类型声明模式。实际上,在方法签名中,类型声明模式不是必需的(就像很多书中所说,应该少用类型声明模式而改用与“ target” 结合的切入点指示符)。但如果指定了类型声明模式,切入点将只匹配对由模式匹配的类型(或者超类型)声明的方法的调用。和其他类型模式一样,类型声明模式支持上述的通配符。同时,它也支持复合类型模式。对于类型声明模式来说,程序员容易犯错的地方在于类型声明模式是基于静态类型而不是运行时类型,这也是本文的主要内容。
在很好地理解类型声明模式之前,先看一下下面的例子:public void foo(){
System.out.println( " A.foo() " );
}
}
public class B extends A{
public void foo(){
System.out.println( " B.foo() " );
}
}
public class Main {
public static void main(String[] args) {
A b = new B();
b.foo(); // (1)
callFoo(b); // (2)
}
public static void callFoo(A a){
System.out.println( " Call A " );
}
public static void callFoo(B b){
System.out.println( " Call B " );
}
}