`
zxl359592450
  • 浏览: 2687 次
  • 性别: Icon_minigender_1
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

讨论AspectJ之target、this、within关键字差异性

阅读更多

今天学习了一下AspectJ,查看了官方文档,查阅了很多其他技术博客,发现大部分人对关键字target、this、within之间差异不是特别清楚,所以引入本文来详细讨论它们之间的区别。特别介绍http://blog.csdn.net/zl3450341/article/details/7673979此文,本片验证思路来源于此并做了扩充说明。

 

1.首先,AspectJ官方怎么描述这三个关键字:

this(SomeType):when the object currently executing (i.e. this) is of type SomeType

当前执行对象是否是某种类型

target(SomeType):when the target object is of type SomeType

目标对象是否是某种类型

within(MyClass):when the executing code belongs to class MyClass

当前执行代码是否属于某个类

此处需要注意的是"对象是否是某种类型"A和“执行代码属于某个类的区别”B,描述A应该具有面向对象特性(继承)。

 

2.其次,关于call与execution两个关键字

execution(void Point.setX(int)):when a particular method body executes

当特定方法体执行时

call(void Point.setX(int)):when a method is called

当一个方法被调用时

此处不同的切点类型对后面使用this与within时的语义理解有影响

 

3.测试验证

基础类

public interface Animal

{

    public void move();

}

 

public class Snake implements Animal

{

 

    @Override

    public void move()

    {

        System.out.println("snake is crawling.");

        System.out.println();

    }

}

 

public class Bird implements Animal

{

 

    @Override

    public void move()

    {

        System.out.println("bird is flying.");

        System.out.println();

    }

}

 

public class TestDifferentBetweenThisTargetWithin

{

    private List<Animal> animals = new ArrayList<Animal>();

 

    @Before

    public void setUp()

    {

        animals.clear();

        animals.add(new Bird());

        animals.add(new Snake());

    }

 

    public void move()

    {

        for (Animal a : animals)

        {

            a.move();

        }

    }

 

    @Test

    public void testDifferent()

    {

        move();

    }

}

 

AspectJ相关

public aspect AspectDifferent

{

 pointcut moveCall():call(public void move()) 

 pointcut moveExecution():execution(public void move())

 

before() :moveCall()

    {

        System.out.println();

        System.out.println("thisJoinPoint:" + thisJoinPoint);

        System.out.println("Kind:" + thisJoinPoint.getKind());

        System.out.println("Target:" + thisJoinPoint.getTarget().getClass());

        System.out.println("This:" + thisJoinPoint.getThis().getClass());

        System.out.println("SourceLineNumber:" + thisJoinPoint.getSourceLocation());

    }

 

before() :moveExecution()

    {

        System.out.println();

        System.out.println("thisJoinPoint:" + thisJoinPoint);

        System.out.println("Kind:" + thisJoinPoint.getKind());

        System.out.println("Target:" + thisJoinPoint.getTarget().getClass());

        System.out.println("This:" + thisJoinPoint.getThis().getClass());

        System.out.println("SourceLineNumber:" + thisJoinPoint.getSourceLocation());

    }

 

4.测试结果(有点多,看起来有点花眼,请仔细看target object与this object的信息,特别是使用call与execution对this的影响):

 

1 pointcut moveCall():call(public void move());拦截到的方法数为3

切点语义描述:所有调用公开的没有返回值的名为move的方法

输出结果:

thisJoinPoint:call(void aspectJ.test.TestDifferentBetweenThisTargetWithin.move())

Kind:method-call

Target:class aspectJ.test.TestDifferentBetweenThisTargetWithin

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

 

thisJoinPoint:call(void aspectJ.Animal.move())

Kind:method-call

Target:class aspectJ.Bird

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

bird is flying.

 

thisJoinPoint:call(void aspectJ.Animal.move())

Kind:method-call

Target:class aspectJ.Snake

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

snake is crawling.

 

2 pointcut moveCall():call(public void move()) && target(Animal);方法数2

语义描述:所有调用公开的没有返回值的名为move的方法并且目标对象是Animal类型

输出结果:

thisJoinPoint:call(void aspectJ.Animal.move())

Kind:method-call

Target:class aspectJ.Bird

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

bird is flying.

 

 

thisJoinPoint:call(void aspectJ.Animal.move())

Kind:method-call

Target:class aspectJ.Snake

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

snake is crawling.

 

3 pointcut moveCall():call(public void move()) && target(Bird);方法数1

语义描述:所有调用公开的没有返回值的名为move的方法并且目标对象是Bird类型

输出结果:

thisJoinPoint:call(void aspectJ.Animal.move())

Kind:method-call

Target:class aspectJ.Bird

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

bird is flying.

 

snake is crawling.

 

4 pointcut moveCall():call(public void move()) && target(Snake);方法数1

语义描述:所有调用公开的没有返回值的名为move的方法并且目标对象是Snake类型

输出结果:

bird is flying.

 

 

thisJoinPoint:call(void aspectJ.Animal.move())

Kind:method-call

Target:class aspectJ.Snake

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

snake is crawling.

 

5 pointcut moveCall():call(public void move()) && target(TestDifferentBetweenThisTargetWithin);方法数1

语义描述:所有调用公开的没有返回值的名为move的方法并且目标对象是TestDifferentBetweenThisTargetWithin类型

输出结果:

thisJoinPoint:call(void aspectJ.test.TestDifferentBetweenThisTargetWithin.move())

Kind:method-call

Target:class aspectJ.test.TestDifferentBetweenThisTargetWithin

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

 

bird is flying.

 

snake is crawling.

 

6 pointcut moveCall():call(public void move()) && this(Animal);方法数0

语义描述:所有调用公开的没有返回值的名为move的方法并且当前执行调用对象是Animal类型

输出结果:

bird is flying.

 

snake is crawling.

 

7 pointcut moveCall():call(public void move()) && this(Bird); 方法数0

语义描述:所有调用公开的没有返回值的名为move的方法并且当前执行调用对象是Bird类型

输出结果:

bird is flying.

 

snake is crawling.

 

8 pointcut moveCall():call(public void move()) && this(Snake);方法数0

语义描述:所有调用公开的没有返回值的名为move的方法并且当前执行调用对象是Snake类型

输出结果:

bird is flying.

 

snake is crawling.

 

9 pointcut moveCall():call(public void move()) && this(TestDifferentBetweenThisTargetWithin);方法数3

语义描述:所有调用公开的没有返回值的名为move的方法并且当前执行调用对象是TestDifferentBetweenThisTargetWithin类型

输出结果:

thisJoinPoint:call(void aspectJ.test.TestDifferentBetweenThisTargetWithin.move())

Kind:method-call

Target:class aspectJ.test.TestDifferentBetweenThisTargetWithin

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

 

 

thisJoinPoint:call(void aspectJ.Animal.move())

Kind:method-call

Target:class aspectJ.Bird

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

bird is flying.

 

 

thisJoinPoint:call(void aspectJ.Animal.move())

Kind:method-call

Target:class aspectJ.Snake

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

snake is crawling.

 

10 pointcut moveCall():call(public void move()) && within(Animal);方法数0

语义描述:所有调用公开的没有返回值的名为move的方法并且当前执行调用的代码属于Animal类

输出结果:

bird is flying.

 

snake is crawling.

 

11 pointcut moveCall():call(public void move()) && within(Bird);方法数0

语义描述:所有调用公开的没有返回值的名为move的方法并且当前执行调用的代码属于Bird类

输出结果:

bird is flying.

 

snake is crawling.

 

12 pointcut moveCall():call(public void move()) && within(Snake);方法数0

语义描述:所有调用公开的没有返回值的名为move的方法并且当前执行调用的代码属于Snake类

输出结果:

bird is flying.

 

snake is crawling.

 

13 pointcut moveCall():call(public void move()) && within(TestDifferentBetweenThisTargetWithin);方法数3

语义描述:所有调用公开的没有返回值的名为move的方法并且当前执行调用的代码属于TestDifferentBetweenThisTargetWithin类

输出结果:

thisJoinPoint:call(void aspectJ.test.TestDifferentBetweenThisTargetWithin.move())

Kind:method-call

Target:class aspectJ.test.TestDifferentBetweenThisTargetWithin

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

 

 

thisJoinPoint:call(void aspectJ.Animal.move())

Kind:method-call

Target:class aspectJ.Bird

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

bird is flying.

 

 

thisJoinPoint:call(void aspectJ.Animal.move())

Kind:method-call

Target:class aspectJ.Snake

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

snake is crawling.

 

14 pointcut moveExecution():execution(public void move());方法数3

语义描述:所有公开的没有返回值的名为move的执行方法体

输出结果:

thisJoinPoint:execution(void aspectJ.test.TestDifferentBetweenThisTargetWithin.move())

Kind:method-execution

Target:class aspectJ.test.TestDifferentBetweenThisTargetWithin

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

 

 

thisJoinPoint:execution(void aspectJ.Bird.move())

Kind:method-execution

Target:class aspectJ.Bird

This:class aspectJ.Bird

bird is flying.

 

 

thisJoinPoint:execution(void aspectJ.Snake.move())

Kind:method-execution

Target:class aspectJ.Snake

This:class aspectJ.Snake

snake is crawling.

 

15 pointcut moveExecution():execution(public void move()) && target(Animal); 方法数2

语义描述:所有公开的没有返回值的名为move的执行方法体并且目标对象是Animal

输出结果:

thisJoinPoint:execution(void aspectJ.Bird.move())

Kind:method-execution

Target:class aspectJ.Bird

This:class aspectJ.Bird

bird is flying.

 

 

thisJoinPoint:execution(void aspectJ.Snake.move())

Kind:method-execution

Target:class aspectJ.Snake

This:class aspectJ.Snake

snake is crawling.

 

16 pointcut moveExecution():execution(public void move()) && target(Bird); 方法数1

语义描述:所有公开的没有返回值的名为move的执行方法体并且目标对象是Bird

输出结果:

thisJoinPoint:execution(void aspectJ.Bird.move())

Kind:method-execution

Target:class aspectJ.Bird

This:class aspectJ.Bird

bird is flying.

 

snake is crawling.

 

17 pointcut moveExecution():execution(public void move()) && target(Snake); 方法数1

语义描述:所有公开的没有返回值的名为move的执行方法体并且目标对象是Snake

输出结果:

bird is flying.

 

 

thisJoinPoint:execution(void aspectJ.Snake.move())

Kind:method-execution

Target:class aspectJ.Snake

This:class aspectJ.Snake

snake is crawling.

 

18 pointcut moveExecution():execution(public void move()) && target(TestDifferentBetweenThisTargetWithin);方法数1

语义描述:所有公开的没有返回值的名为move的执行方法体并且目标对象是TestDifferentBetweenThisTargetWithin

输出结果:

thisJoinPoint:execution(void aspectJ.test.TestDifferentBetweenThisTargetWithin.move())

Kind:method-execution

Target:class aspectJ.test.TestDifferentBetweenThisTargetWithin

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

 

bird is flying.

 

snake is crawling.

 

19 pointcut moveExecution():execution(public void move()) && this(Animal);方法数2

语义描述:所有公开的没有返回值的名为move的执行方法体并且执行这个执行方法体动作的对象是Animal类型,也就是说当前实例方法体的实例主体是Animal类型

输出结果:

thisJoinPoint:execution(void aspectJ.Bird.move())

Kind:method-execution

Target:class aspectJ.Bird

This:class aspectJ.Bird

bird is flying.

 

 

thisJoinPoint:execution(void aspectJ.Snake.move())

Kind:method-execution

Target:class aspectJ.Snake

This:class aspectJ.Snake

snake is crawling.

 

20 pointcut moveExecution():execution(public void move()) && this(Bird);方法数1

语义描述:所有公开的没有返回值的名为move的执行方法体并且执行这个执行方法体动作的对象是Bird类型,也就是说当前实例方法体的实例主体是Bird类型

输出结果:

thisJoinPoint:execution(void aspectJ.Bird.move())

Kind:method-execution

Target:class aspectJ.Bird

This:class aspectJ.Bird

bird is flying.

 

snake is crawling.

 

21 pointcut moveExecution():execution(public void move()) && this(Snake); 方法数1

语义描述:所有公开的没有返回值的名为move的执行方法体并且执行这个执行方法体动作的对象是Snake类型,也就是说当前实例方法体的实例主体是Snake类型

输出结果:

bird is flying.

 

 

thisJoinPoint:execution(void aspectJ.Snake.move())

Kind:method-execution

Target:class aspectJ.Snake

This:class aspectJ.Snake

snake is crawling.

 

22 pointcut moveExecution():execution(public void move()) && this(TestDifferentBetweenThisTargetWithin);方法数1

语义描述:所有公开的没有返回值的名为move的执行方法体并且执行这个执行方法体动作的对象是TestDifferentBetweenThisTargetWithin类型,也就是说当前实例方法体的实例主体是TestDifferentBetweenThisTargetWithin类型

输出结果:

thisJoinPoint:execution(void aspectJ.test.TestDifferentBetweenThisTargetWithin.move())

Kind:method-execution

Target:class aspectJ.test.TestDifferentBetweenThisTargetWithin

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

 

bird is flying.

 

snake is crawling.

 

23 pointcut moveExecution():execution(public void move()) && within(Animal);方法数0

语义描述:所有公开的没有返回值的名为move的执行方法体并且这个方法体执行代码是属于Animal类

输出结果:

bird is flying.

 

snake is crawling.

 

24 pointcut moveExecution():execution(public void move()) && within(Bird); 方法数1

语义描述:所有公开的没有返回值的名为move的执行方法体并且这个方法体执行代码是属于Bird类

输出结果:

thisJoinPoint:execution(void aspectJ.Bird.move())

Kind:method-execution

Target:class aspectJ.Bird

This:class aspectJ.Bird

bird is flying.

 

snake is crawling.

 

25 pointcut moveExecution():execution(public void move()) && within(Snake); 方法数1

语义描述:所有公开的没有返回值的名为move的执行方法体并且这个方法体执行代码是属于Snake类

输出结果:

bird is flying.

 

 

thisJoinPoint:execution(void aspectJ.Snake.move())

Kind:method-execution

Target:class aspectJ.Snake

This:class aspectJ.Snake

snake is crawling.

 

26 pointcut moveExecution():execution(public void move()) && within(TestDifferentBetweenThisTargetWithin);方法数1

语义描述:所有公开的没有返回值的名为move的执行方法体并且这个方法体执行代码是属于TestDifferentBetweenThisTargetWithin类

输出结果:

thisJoinPoint:execution(void aspectJ.test.TestDifferentBetweenThisTargetWithin.move())

Kind:method-execution

Target:class aspectJ.test.TestDifferentBetweenThisTargetWithin

This:class aspectJ.test.TestDifferentBetweenThisTargetWithin

 

bird is flying.

 

snake is crawling.

 

5.测试结论:

无论是使用call还是execution类型pointcut,target对象均不会受影响,target可以理解为拥有move方法(move方法在某个类中定义)的实例是什么类型。(所以2,15;3,16;4,17;5,18结果相同)

 

使用call类型 pointcut时,this可以理解为调用move这个方法的实例是什么类型。(上面测试中所有call的this object都是TestDifferentBetweenThisTargetWithin,所以6,7,8均没有拦截到方法,9拦截数量为3)

 

使用execution类型 pointcut时,this可以理解为拥有move方法(move方法在某个类中定义)的实例是什么类型,与target相同(19,20,21,22)。

 

Target与this均支持继承(描述都是“是什么类型“),within不支持(描述是”代码属于哪个类“)。

 

上面测试中所有调用move方法都是TestDifferentBetweenThisTargetWithin,所以10,11,12拦截数为0, 13拦截数为3

 

上面测试用所有move方法的执行都是在各自类中,所以23拦截数为0, 24,25,26拦截数分别为1

 

以上所有欢迎讨论。

 

分享到:
评论

相关推荐

    Aop之AspectJ详解解读demo

    **Aop之AspectJ详解解读** 在软件开发中,面向切面编程(AOP)是一种设计模式,它允许程序员将关注点分离到不同的模块,从而提高代码的可维护性和复用性。AspectJ是Java平台上的一个开源AOP框架,它提供了一种强大...

    AspectJ 文档

    AspectJ的核心概念之一是连接点(Join point),它是指那些可以被声明为切面目标的特定点。在AspectJ中,可以声明的连接点包括方法调用、方法执行、构造器调用、构造器执行、字段获取、字段设置、初始化代码块、静态...

    Aspectj

    AspectJ是一种广泛使用的Java语言的面向切面编程(AOP)扩展。它允许开发者将关注点模块化,使得系统中的交叉切面(如日志、事务管理、安全性等)可以独立于核心业务逻辑进行处理。本指南将深入探讨AspectJ的核心概念...

    aspectj-1.9.6.jar

    AspectJ是Java平台上的一种面向切面编程(AOP)框架,它允许开发者将关注点分离,提高代码的可维护性和可复用性。AspectJ 1.9.6.jar文件是AspectJ库的核心组成部分,它是开发者在Java环境中实现AOP的关键依赖。 ...

    aspectJ

    6. **应用领域**:AspectJ广泛应用于日志记录、事务管理、权限控制、性能监控等系统级服务,使得这些关注点可以从核心业务逻辑中分离出来,提高了代码的可维护性和复用性。 学习AspectJ,你需要理解其基本概念,并...

    aspectj-1.7.0.jar

    aspectj-1.7.0.jar aspectj的包

    精通AspectJ_源代码

    AspectJ是一种强大的面向方面的编程(AOP)框架,它扩展了Java语言,使得开发者能够更方便地处理系统中的横切关注点,如日志、事务管理、安全性等。本资源包含的是《精通AspectJ》一书中的示例代码,通过这些代码,...

    Java JDK代理、CGLIB、AspectJ代理分析比较

    this.target = target; } // 实际执行类bind public Object bind(Object real) { this.real = real; // 利用JDK提供的Proxy实现动态代理 return Proxy.newProxyInstance(target.getClassLoader(), new ...

    aspectj-1.6.9.jar

    AspectJ 是一个强大的面向切面编程(AOP)的框架,它允许开发者在Java应用程序中分离关注点,将横切逻辑(如日志、事务管理、安全性等)与核心业务逻辑相分离。`aspectj-1.6.9.jar` 是AspectJ框架的一个特定版本,即...

    book :aspectj in action

    “工具”标签则可能意味着书中讨论了AspectJ与其他开发工具的结合,如构建工具Maven或Gradle中的AspectJ插件,以及如何在持续集成环境中应用AspectJ。此外,书中可能还提到了AspectJ的开发和调试工具,如AspectJ ...

    aspectj jar

    AspectJ的引入极大地增强了Spring的AOP能力,使得我们可以更优雅地处理横切关注点,提高代码的可读性和可维护性。同时,由于AspectJ提供了类型安全的注解和强大的切入点表达式,开发者可以更准确地控制切面的生效...

    AspectJ的JAR包

    AspectJ是一种强大的面向切面编程(AOP)框架,它扩展了Java语言,允许开发者在不改变原有代码结构的情况下,插入关注点代码。在Spring AOP框架中,AspectJ被广泛用于实现更精细粒度的切面逻辑,提供比Spring默认的...

    AspectJ_Cookbook_English_edition

    《AspectJ Cookbook》是一本专为开发者准备的指南,它深入介绍了AspectJ这一强大的面向切面编程(AOP)框架。面向切面编程是一种编程范式,旨在提高软件的可维护性和可重用性,通过将关注点分离,使得业务逻辑与系统...

    Aspectj5学习文档

    此外,AspectJ5还支持运行时类型和上下文的暴露,例如@this、@target、@args、@within、@withincode、@annotation等,这些注解能够帮助开发者在运行时获取到更多类型和上下文的信息,使得对程序的控制和调试更加容易...

    AspectJ in Action 2nd Edition

    - **技术前瞻性**:本书对AOP的发展趋势进行了展望,并讨论了AspectJ如何适应这些变化。 - **读者评价**:众多专业评论家和开发者对该书给予了高度评价,认为它是学习AspectJ的最佳指南之一。 #### 知识点四:书籍...

    org.aspectj,aspectj项目库(org.aspectj).zip

    【标题】"org.aspectj,aspectj项目库(org.aspectj).zip" 提供的是开源项目AspectJ的源码库。AspectJ是一种强大的面向切面编程(AOP)框架,它扩展了Java语言,允许程序员以声明式方式处理系统的横切关注点,如日志...

    AspectJ面向切面的例子

    游戏中的每个动作都能看作是一个潜在的切入点,AspectJ可以通过织入(weaving)来插入相应的切面逻辑,确保游戏运行的流畅性和正确性。 标签"面向切面"和"AspectJ"进一步强调了这个例子的核心内容。面向切面编程...

    AspectJ Cookbook中文版

    然而,尽管aspectj纳入在eclipse这个日益流行的java开源ide之内,但是找到一种实用、非理论的方式来学习这种语言及其他aop工具和技术已经成为一个实际的问题。  迄今为止,本书提供了实用的解决方案以及大量的代码...

Global site tag (gtag.js) - Google Analytics