边城愚人

如果我不在边城,我一定是在前往边城的路上。

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  31 随笔 :: 0 文章 :: 96 评论 :: 0 Trackbacks

        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)使用静态的类型声明的图示:

Screenshot3.png


Screenshot4.png


       可以看到,在方面AspectDemo中,before通知的左面有一个向上的小箭头表示其为通知,而Zoo中的void speak()方法中a.speak();一行的左面有个向右的小箭头,表明其匹配了一个通知(也就是AspectDemo中的before通知)。
       2)
使用target的图示:

Screenshot1.png

Screenshot2.png

       和静态的类型声明不同,使用了target的before前的箭头上有个问号,以表明target动态的不确定性。而Zoo的main中调用的方法z.speak()前有个类似于speak()中的a.speak();的箭头,不同的是,z.speak()前的箭头上有个问号,这表明此处speak()并不确定是否匹配通知(因为target是动态确定连接点)。而实际上情况是,z.speak()确实不是通知的连接点。

        对于targetIdentifier)的使用,示例如下:

    publicpointcut speakCallTwo(Object o):

        call(* Animal.speak()) && target(o);

        before(Object o):speakCallTwo(o){

                System.out.println(o.getClass());

        }

    }

        通过将 target付给 Object o,可以在before通知中调用 o的一些操作。

        thistarget指示符的一个补充,它的格式与target相同。在含义上,this表示切入点所匹配的方法的调用类,而target表示匹配方法的目标类。例如:

        publicpointcut anotherSpeakCall():

            call(* speak()) && target(Animal) && this(Zoo);

        target(Animal) 表示void speak()方法是Animal及子类的,它不会匹配 Zoovoid speak()方法。而this(Zoo)会匹配调用了Animal及子类的void speak()方法的 Zoo类的方法,这里就是Zoovoid speak()方法。

        如上便是关于targetthis的基本用法。该文参考了《Eclipse AspectJ》和《AspectJ cookbook》。

posted on 2007-07-09 09:17 kafka0102 阅读(2325) 评论(3)  编辑  收藏 所属分类: AOP

评论

# re: AspectJ学习(2)使用切入点 target和this 2008-05-09 08:32 davide520
谢谢博主.  回复  更多评论
  

# re: AspectJ学习(2)使用切入点 target和this[未登录] 2008-11-01 09:42 piggy
不错,受益了.  回复  更多评论
  

# re: AspectJ学习(2)使用切入点 target和this[未登录] 2011-03-16 13:12 max
target() and this() work only for non-static methods  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: