今天学习了一下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详解解读** 在软件开发中,面向切面编程(AOP)是一种设计模式,它允许程序员将关注点分离到不同的模块,从而提高代码的可维护性和复用性。AspectJ是Java平台上的一个开源AOP框架,它提供了一种强大...
AspectJ的核心概念之一是连接点(Join point),它是指那些可以被声明为切面目标的特定点。在AspectJ中,可以声明的连接点包括方法调用、方法执行、构造器调用、构造器执行、字段获取、字段设置、初始化代码块、静态...
AspectJ是一种广泛使用的Java语言的面向切面编程(AOP)扩展。它允许开发者将关注点模块化,使得系统中的交叉切面(如日志、事务管理、安全性等)可以独立于核心业务逻辑进行处理。本指南将深入探讨AspectJ的核心概念...
AspectJ是Java平台上的一种面向切面编程(AOP)框架,它允许开发者将关注点分离,提高代码的可维护性和可复用性。AspectJ 1.9.6.jar文件是AspectJ库的核心组成部分,它是开发者在Java环境中实现AOP的关键依赖。 ...
6. **应用领域**:AspectJ广泛应用于日志记录、事务管理、权限控制、性能监控等系统级服务,使得这些关注点可以从核心业务逻辑中分离出来,提高了代码的可维护性和复用性。 学习AspectJ,你需要理解其基本概念,并...
aspectj-1.7.0.jar aspectj的包
AspectJ是一种强大的面向方面的编程(AOP)框架,它扩展了Java语言,使得开发者能够更方便地处理系统中的横切关注点,如日志、事务管理、安全性等。本资源包含的是《精通AspectJ》一书中的示例代码,通过这些代码,...
this.target = target; } // 实际执行类bind public Object bind(Object real) { this.real = real; // 利用JDK提供的Proxy实现动态代理 return Proxy.newProxyInstance(target.getClassLoader(), new ...
AspectJ 是一个强大的面向切面编程(AOP)的框架,它允许开发者在Java应用程序中分离关注点,将横切逻辑(如日志、事务管理、安全性等)与核心业务逻辑相分离。`aspectj-1.6.9.jar` 是AspectJ框架的一个特定版本,即...
“工具”标签则可能意味着书中讨论了AspectJ与其他开发工具的结合,如构建工具Maven或Gradle中的AspectJ插件,以及如何在持续集成环境中应用AspectJ。此外,书中可能还提到了AspectJ的开发和调试工具,如AspectJ ...
AspectJ的引入极大地增强了Spring的AOP能力,使得我们可以更优雅地处理横切关注点,提高代码的可读性和可维护性。同时,由于AspectJ提供了类型安全的注解和强大的切入点表达式,开发者可以更准确地控制切面的生效...
AspectJ是一种强大的面向切面编程(AOP)框架,它扩展了Java语言,允许开发者在不改变原有代码结构的情况下,插入关注点代码。在Spring AOP框架中,AspectJ被广泛用于实现更精细粒度的切面逻辑,提供比Spring默认的...
《AspectJ Cookbook》是一本专为开发者准备的指南,它深入介绍了AspectJ这一强大的面向切面编程(AOP)框架。面向切面编程是一种编程范式,旨在提高软件的可维护性和可重用性,通过将关注点分离,使得业务逻辑与系统...
此外,AspectJ5还支持运行时类型和上下文的暴露,例如@this、@target、@args、@within、@withincode、@annotation等,这些注解能够帮助开发者在运行时获取到更多类型和上下文的信息,使得对程序的控制和调试更加容易...
- **技术前瞻性**:本书对AOP的发展趋势进行了展望,并讨论了AspectJ如何适应这些变化。 - **读者评价**:众多专业评论家和开发者对该书给予了高度评价,认为它是学习AspectJ的最佳指南之一。 #### 知识点四:书籍...
【标题】"org.aspectj,aspectj项目库(org.aspectj).zip" 提供的是开源项目AspectJ的源码库。AspectJ是一种强大的面向切面编程(AOP)框架,它扩展了Java语言,允许程序员以声明式方式处理系统的横切关注点,如日志...
游戏中的每个动作都能看作是一个潜在的切入点,AspectJ可以通过织入(weaving)来插入相应的切面逻辑,确保游戏运行的流畅性和正确性。 标签"面向切面"和"AspectJ"进一步强调了这个例子的核心内容。面向切面编程...
然而,尽管aspectj纳入在eclipse这个日益流行的java开源ide之内,但是找到一种实用、非理论的方式来学习这种语言及其他aop工具和技术已经成为一个实际的问题。 迄今为止,本书提供了实用的解决方案以及大量的代码...