??? ??? target
切入點(diǎn)格式如下:
target
([
Type
|
Identifier
])。
Type
指示對(duì)連接點(diǎn)處的對(duì)象類型提供一個(gè)靜態(tài)編譯時(shí)評(píng)估,并采用完全限定類名的形式(也就是說,
Type
不能是使用通配符的類型聲明模式)。
Identifier
提供了一種方法,可通過它來評(píng)估連節(jié)點(diǎn)處的運(yùn)行時(shí)對(duì)象的實(shí)際類型,而不僅僅是靜態(tài)類型。
Identifier
在運(yùn)行時(shí)動(dòng)態(tài)地賦予合適的對(duì)象。
??? ??? 下面通過例子說明一下
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();
??? ??? }
??? }
}
???
定義一個(gè)切入點(diǎn)如下:
public
pointcut
speakCallOne():
??? call
(*
speak()) &&
target
(Animal);
??? ??? 雖然
pointcut
speakCallOne()
中的
call
(*
speak())
匹配所有類的
speak()
方法(這里匹配
Cat
、
Dog
、
Zoo
),但
target
(Animal)
便將
pointcut
speakCallOne()
限定在
Animal
及其子類(也就是
Cat
、
Dog
,而不包含
Zoo
)。這里當(dāng)然可以使用
call
(*
Animal.speak())
來代替
target
。和靜態(tài)的類型聲明不同,
target
并不能靜態(tài)地確定的每一個(gè)連接點(diǎn),因?yàn)槠ヅ涫腔谶\(yùn)行時(shí)的類型信息。在使用
AJDT
的情況下,可以看到
target
和靜態(tài)的類型聲明的不同:
??? ?? 1)使用
靜態(tài)的類型聲明的圖示:
??? ?? 可以看到,在方面AspectDemo中,before通知的左面有一個(gè)向上的小箭頭表示其為通知,而Zoo中的void speak()方法中a.speak();一行的左面有個(gè)向右的小箭頭,表明其匹配了一個(gè)通知(也就是AspectDemo中的before通知)。
??? ?? 2)使用
target的圖示:


??? ?? 和靜態(tài)的類型聲明不同,使用了target的before前的箭頭上有個(gè)問號(hào),以表明target動(dòng)態(tài)的不確定性。而Zoo的main中調(diào)用的方法z.speak()前有個(gè)類似于speak()中的a.speak();的箭頭,不同的是,z.speak()前的箭頭上有個(gè)問號(hào),這表明此處speak()并不確定是否匹配通知(因?yàn)閠arget是動(dòng)態(tài)確定連接點(diǎn))。而實(shí)際上情況是,z.speak()確實(shí)不是通知的連接點(diǎn)。
??? ??? 對(duì)于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通知中調(diào)用
o的一些操作。
??? ??? this是target指示符的一個(gè)補(bǔ)充,它的格式與target相同。在含義上,this表示切入點(diǎn)所匹配的方法的調(diào)用類,而target表示匹配方法的目標(biāo)類。例如:
??? ??? publicpointcut
anotherSpeakCall():
??? ??? ??? call(*
speak()) && target(Animal)
&& this(Zoo);
??? ??? target(Animal)
表示void
speak()方法是Animal及子類的,它不會(huì)匹配
Zoo的void
speak()方法。而this(Zoo)會(huì)匹配調(diào)用了Animal及子類的void
speak()方法的
Zoo類的方法,這里就是Zoo的void
speak()方法。
??? ??? 如上便是關(guān)于target和this的基本用法。該文參考了《Eclipse
AspectJ》和《AspectJ
cookbook》。