??? ??? target 切入點格式如下: target ([ Type | Identifier ])。 Type 指示對連接點處的對象類型提供一個靜態編譯時評估,并采用完全限定類名的形式(也就是說, Type 不能是使用通配符的類型聲明模式)。 Identifier 提供了一種方法,可通過它來評估連節點處的運行時對象的實際類型,而不僅僅是靜態類型。 Identifier 在運行時動態地賦予合適的對象。
??? ??? 下面通過例子說明一下 target 的使用:
public interface Animal {
??? void speak();
}
public class Cat implements Animal{
??? public void speak() {
??? ??? System. out .println( " 喵喵 " );
??? }
}
public class Dog implements Animal{
??? public void speak() {
??? ??? System. out .println( " 汪汪 " );
??? }
}
public class Zoo {
??? private List<Animal> animals = new ArrayList<Animal>();
??? public void addAnimal(Animal a){
??? ??? animals .add(a);
??? }
??? public void speak(){
??? ??? for (Animal a : animals ){
??? ??? ??? ??? a.speak();
??? ??? }
??? }
}
???
定義一個切入點如下:
public pointcut speakCallOne():
??? call (* speak()) && target (Animal);
??? ??? 雖然 pointcut speakCallOne() 中的 call (* speak()) 匹配所有類的 speak() 方法(這里匹配 Cat 、 Dog 、 Zoo ),但 target (Animal) 便將 pointcut speakCallOne() 限定在 Animal 及其子類(也就是 Cat 、 Dog ,而不包含 Zoo )。這里當然可以使用 call (* Animal.speak()) 來代替 target 。和靜態的類型聲明不同, target 并不能靜態地確定的每一個連接點,因為匹配是基于運行時的類型信息。在使用 AJDT 的情況下,可以看到 target 和靜態的類型聲明的不同:
??? ?? 1)使用靜態的類型聲明的圖示:

??? ?? 2)使用target的圖示:


??? ??? 對于target(Identifier)的使用,示例如下:
??? publicpointcut speakCallTwo(Object o):
??? ??? call(* Animal.speak()) && target(o);
??? ??? before(Object o):speakCallTwo(o){
??? ??? ??? ??? System.out.println(o.getClass());
??? ??? }
??? }
??? ??? 通過將 target付給 Object o,可以在before通知中調用 o的一些操作。
??? ??? this是target指示符的一個補充,它的格式與target相同。在含義上,this表示切入點所匹配的方法的調用類,而target表示匹配方法的目標類。例如:
??? ??? publicpointcut anotherSpeakCall():
??? ??? ??? call(* speak()) && target(Animal) && this(Zoo);
??? ??? target(Animal) 表示void speak()方法是Animal及子類的,它不會匹配 Zoo的void speak()方法。而this(Zoo)會匹配調用了Animal及子類的void speak()方法的 Zoo類的方法,這里就是Zoo的void speak()方法。
??? ??? 如上便是關于target和this的基本用法。該文參考了《Eclipse AspectJ》和《AspectJ cookbook》。