`
小嘴冰凉
  • 浏览: 457187 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

AspectJ学习笔记之Pointcut

阅读更多
http://dev.csdn.net/author/CenturyMagus/index.html

该文是我读AspectJ in Action时的一些学习笔记和自己的一些学习总结,当时是用英文记下的(因为书是英文的嘛,嘿嘿,而且个人认为看英文文档更能理解的透彻一些,毕竟是作者的原话嘛),现在放到网上和大家共享,并翻译成中文,如果哪处我翻译的不够恰当,理解的不够准确,请各位看英文部分以获得更准确的信息并给予我指正。(ah011@163.com)

 

Pointcuts

public  pointcut  accountOperations :call(*Account.*(..))

这是定义了一个pointcut,其中:

public 是access specifer

pointcut 是keyword

accountOperations 是poincut name

call是pointcut type;;pointcut能与其他pointcut通过或(||)、与(&&)以及非(!)操作符联合

Account是signature

 

l         常用pointcut类型

1)      call

2)      execution

3)      target

4)      args

5)      within

6)      cflow

 

l         基本概念

如果对上面的概念不是特别了解没有关系,下面就介绍一些基本的概念:

Joint Point

A join point is an identifiable point in the execution of a program. It could be a call to a method or an assignment to a member of an object.

join point 是程序执行过程中可以被识别的点。它可以是对一个函数的调用或是对象的一个属性。(注:spring的AOP只能做到对函数调用的拦截)

例子:

Public class Account

{

 void credit(float amount)

{

       _balance += amount;

}

}

这个例子中的join point包括Account类中执行credit()方法和对_balance的操作。

 

Pointcut

A pointcut is a program construct that selects join points and collects context at those points. For example, a pointcut can select a join point that is a call to a method, and it could also capture the method’s context, such as the target object on which the method was called and the method’s arguments.

We can write a pointcut that will capture the execution of the credit() method in the Account class shown earlier:

execution(void Account.credit(float))

To understand the difference between a join point and pointcut, think of pointcuts as specifying the weaving rules and join points as situations satisfying those rules.

 

pointcut 是一种程序结构,它用于选取join point并收集这些point的上下文信息。举例来说,pointcut可以是一个调用方法的join point,并且它能捕获这个方法的上下文信息,例如调用这个方法的目标对象和该方法的属性。

我们可以写一个pointcut,它将可以捕获前面Account类中credit()方法的执行:

execution(void Account.credit(float))

 

要想理解join point和pointcut的不同,可以把pointcut想成明确了织入的规则,而join point则声明了符合这些规则的情况(即什么情况下运用织入的规则)。

 

l          笔记要点

1.        In AspectJ, pointcut can be either anonymous or named.

aspectj中,poincut可以是匿名的,也可以是命名的。

 

2.        Notice that the name of the pointcut is at the left of the colon and pointcut definition is at the right. The pointcut definition is syntax that identifies the join points where you want to insert some action.

注意,pointcut的名字应位于冒号的左侧,而pointcut的定义在冒号的右侧。point cut的定义明确了你想在哪个join point插入一些动作。

 

3.        Three wildcard notations are available in AspectJ:

1)      * denotes any number of characters expect the period.

2)      .. denotes any number of characters including any number of period.

3)      + denotes any subclass or subinerface of a given type.

Example:

*Account       Types with a name ending with Account such as SavingsAccout and CheckingAccount

java.*.Data    Types Data in any direct subpackages of the java package, such as java.util.Data and java.sql.Data.

java..*           Any type inside the java package or all of its direct subpackage, such as java.awt and java.util, as well as indirect subpackages such as java.awt.event and java.util.logging

 

以下是AspectJ中的三个通配符:

1)      * 表示匹配任意数量的字符,除了句号(.)

2)      .. 表示比配包含句号在内的任意数量的字符。

3)      + 表示比配任意给定的类型的子类和子接口。

例子:

*Account       匹配以Account结尾的类型名,例如SavingsAccout和 

CheckingAccount

java.*.Data  匹配java包下的直接子包下的Data类型,例如java.util.Data和java.sql.Data(注:但不能是java.a.b.Data, 因为*不能包含句号嘛)

java..*           匹配java包下任意类型或者其所有直接子包,例如java.awt和java.util,也可匹配其非直接子包,例如java.awt.event和java.util.logging 

 

4.        Please note that in method signatures, the wildcard .. used to denote any type and number of arguments taken by a method.

Example:

*java.io.Reader.read(char[],.. )

Any read() method in the Reader class irrespective of type and number of arguments to the method as long as the first argument type is char[]. In this case, it will mach read(char[])  and  read(char[], int, int), but not read().

请注意在method signatures中,通配符..被用于表示匹配包含任意类型和任意数量的参数的方法。

例子:

*java.io.Reader.read(char[],.. )

Reader类中的任何read()方法,无论参数是什么类型,数量如何,只要其首参数是char[]类型,就可以匹配。这种情况下,它可以匹配read(char[]),也可以匹配read(char[], int, int),但不能匹配read()。

 

5.        The execution join point is on the method body itself.

执行类型的join point是方法体本身。

Example:


In this code snippet, the point for the execution of the debit() method is the whole method body. This means that we can write advice for this join point to the applied before, after, and around the body.

在这个程序小片段里,debit()方法的执行类型joint point是整个方法体。这意味着我们可以为它写符合要求的advice(通知),包括before、after、around。(注:关于advice,将在下一篇中介绍)

6.        The method call join point occurs at the place where this method is being invoked.

方法调用的join point放生在方法被引用的地方。

Example:

Account account = …...;

account.debit(100);  //debit() method call join point

 

Note that the code that forms the arguments is not a part of the join point. For example, if the debit() method is called in the statement account.debit(Currend.round(100.2345)), the call Current.round(100.2345) is not part of the debit() method call join point.

注意,代码形式的参数不是call join point的一部分。例如如果debit()方法以如下形式调用,account.debit(Currend.round(100.2345)),那么Current.round(100.2345)不是其method call join point的一部分。

 

7.        execution 和call join point 的区别

我的理解是:

1)  在你想针对某个方法进行某些advice的织入时,应该用execution,即当想在某个方法的方法体之前,之后,之中织入某些advice时使用。

Example:


在这段代码中,如果想在debit()的方法体,即


之前、之后、之中织入一些advice时使用。

2)  而call是想在调用某个方法的地方之前、之后织入某些advice时使用的。

Example:

Account account = …...;

account.debit(100);  //即在句前、后加advice时使用。

 

8.        Execution Object Pointcuts (this和target)

1)      These pointcuts match the join points based on the types of the objects at execution time.

这种pointcut用于在运行期匹配对象的类型。

2)      In addition to matching the join points, these pointcuts are used to collect the context at the specified join point.

另外,这种pointcut可以用于收集join point附近的上下文信息。

3)      The this() pointcut takes the form this(Type or ObjectIdentifier); it matches all join points that have a this object associated with them that is of the specified type or the specified ObjectIdentifier’s type. In other words, if you specify Type, it will match the join points where the expression this instanceof <Type> is true. The form of this pointcut that specifies ObjectIdentifier is used to collect the this object. If you need to match without collecting context, you will use the form that uses Type, but if you need to collect the context, you will use the form that uses ObjectIdentifier.

this() 型pointcut的基本形式为this(Type or ObjectIdentifier);它匹配所有有this对象的pointcut,而这些pointcut就是已声明的类型或对象标识符的类型。换句话说就是,如果你声明了Type,当表达式this instanceof <Type>为真时将匹配。声明为ObjectIdentifier的pointcut将用于收集this对象的上下文信息。如果你想只匹配而不收集上下文,可以使用Type,反之则使用ObjectIdentifier

4)      The target() pointcut is similar to the this () pointcut. The target() pointcut is normally used with a method call join point.

target() pointcut 和this() pointcut类似。target() pointcut 一般和call join point 搭配使用。

5)      Example:

this(Account)        All join points where this is instanceof Account. This will match all join points like methods calls and field assignments where the current execution object is Account, or its subclass, for example, SavingsAccount.

target(Account)     All the join points where the object on which the method called is instanceof Account. This will match all join points where the target object is Account, or its subclass, for example, SavingsAccount.

6)      target 匹配的是哪个对象调用了某方法

Example:

ResgisterBuiness rb = new ResgisterBuiness();

forwardName = rb.doRegister(mapping.form);

对于doRegister方法来说,rb就是target

 

9.        Lexical-structure based pointcuts

1)      A lexical scope is a segment of source code. The within() pointcuts take the form of within(TypePattern) and are used to capture all the join points within the body of the specified classes and aspects, as well as any nested classes. The withincode() pointcuts take the form of either withincode(MethodSignature) or withincode(ConstrutorSignature) and are used to capture all the join points inside a lexical structure of constructor or a method, including any local classes in them.

lexical scope就是一个代码段。within() pointcut 形式是within(TypePattern) ,用来捕获声明的类、方面、还有内部类体的所有join point。withincode() pointcut的形式是withincode(MethodSignature)和withincode(ConstrutorSignature),用于捕获构造函数或方法的词法结构内的所有join point,包括它们内部的任何local classes。

2)      One common usage of the within() pointcut is to exclude the join points in the aspect itself. For example, the following pointcut excludes the join point corresponding to the calls to all print methods in the java.io.PrintStream class that occur inside the TraceAspect itself:

call(*java.io.PrintStream.print*(..)) && ! within(TraceAspect)

 

3)      this 和within的作用差不多,以下为不同点:

<1> within包含内部类,但不包含子类

<2> this包含子类,但不包含内部类

 

10.    Argument pointcuts

These pointcuts capture join points based on the argument type of a join point. Similar to execution object pointcuts these pointcuts can be used to capture the context.

Example:

args(String, .. , int)        All the join points in all methods where the first argument is of type String and last argument is of type int.

匹配所有以String为第一个参数类型,以int为最后一个参数类型的方法。

 

11.    Control-flow based pointcuts

1)      The control flow of a join point defines the flow of the program instructions that occur as a result of the invocation of the join point.

join point的控制流定义了程序指令的流程,以join point调用的结果的形式出现。

2)      For example, the Account.debit() method calls Account.getBalance() as a part of its execution; the call and the excution of Account.getBalance() is said to have occurred in the Account.debit() method’s control flow, and therefore it has occurred in the control flow of the join point for the method.

例如:Account.debit()方法调用Account.getBalance()作为它执行的一部分;对Account.getBalance()进行call和execution操作都可以认为是发生在Account.debit()方法的控制流内,所以就是发生在join point的控制流内。

3)      以下是我经过实验后的一些理解:

接着上面的例子,如果Account.getBalance()中又调用了另一个方法,例如abc(),那么abc()的join point也属于Account.debit()的control-flow,也即不管经过了多少层的调用关系,用control-flow pointcut都可以判断出某个join point是否属于一个control-flow;这一点上和within()又有一定的区别,within只能判别出join point是否在一个代码块中出现过,即只能表示一层关系。

4)      cflow(call(*Account.debit(..)) 任何在debit() control-flow中的join point都将被捕获,包括对debit()自身的call(即cflow()被用在了debit()自己的pointcut时的情况)

cflowbelow(call(*Account.debit(..)) 不包括对debit()自身的call




分享到:
评论

相关推荐

    spring aop 学习笔记

    本学习笔记将深入探讨Spring AOP的核心概念、工作原理以及实际应用。 1. **核心概念** - **切面(Aspect)**:切面是关注点的模块化,包含业务逻辑之外的横切关注点,如日志、事务管理。 - **连接点(Join Point...

    Spring学习笔记

    ### Spring学习笔记:深入理解AOP与Annotation驱动的动态代理 #### 核心知识点解析: 在探讨Spring框架中AOP(面向切面编程)及基于Annotation的动态代理之前,我们首先需要了解AOP的基本概念及其在Spring中的实现...

    牛人的spring学习笔记,非常适合初学者

    ### 牛人的Spring学习笔记,非常适合初学者 #### 第一课:面向抽象编程 面向抽象编程是一种编程思想,强调在程序设计过程中通过定义抽象层来分离业务逻辑与具体实现细节。这种方式有助于提高软件的可维护性和扩展...

    spring mvc学习笔记

    ### Spring MVC 学习笔记之 AOP 面向切面编程详解 #### 一、AOP 概念概述 面向切面编程(Aspect Oriented Programming, AOP)是一种编程范式,它允许程序员定义“切面”来封装那些与业务逻辑本身无关的功能,比如...

    spring2.5 学习笔记

    【Spring 2.5 学习笔记】 在深入学习Spring 2.5的过程中,我们可以了解到一系列关键的概念和技术。首先,面向抽象编程是Spring的核心理念之一,它鼓励开发者编写可重用且松散耦合的代码,通过接口而非具体实现进行...

    spring的学习笔记

    - **AspectJ切入点语法详解**:AspectJ是Spring支持的AOP语言,用于定义切点表达式,精确匹配需要织入通知的方法。 ### 4. **资源管理** Spring提供了丰富的资源管理能力,如文件、URL、数据库连接等: - **4.1 ...

    spring2.5学习笔记

    ### Spring2.5 学习笔记关键知识点梳理 #### 搭建Spring的运行环境 - **新建项目**: 使用IDE工具如Eclipse或IntelliJ IDEA创建一个新的Java Web项目。 - **Spring配置文件**: 在项目的`src/main/resources`目录下...

    spring学习笔记(十三)

    【标题】"Spring学习笔记(十三)"主要涉及的是Spring框架中的AOP(面向切面编程)部分,特别是关于CGLIB动态代理的实现。在Spring中,AOP是一种强大的编程模型,它允许开发者定义“切面”,即关注点的模块化,如日志...

    spring2.5_学习笔记.

    ### Spring2.5 学习笔记知识点概览 #### 第一课:面向抽象编程 - **概念理解**:面向抽象编程是一种设计模式,其核心思想是通过定义接口或抽象类来实现程序结构的设计,使具体实现与接口分离,增强系统的灵活性和...

    SpringAop学习笔记以及实现Demo

    **Spring AOP 学习笔记及实现Demo** Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架中的一个重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。AOP的主要目的...

    Spring学习笔记(16)----使用Spring配置文件实现AOP

    在本篇Spring学习笔记中,我们将深入探讨如何利用Spring配置文件来实现面向切面编程(AOP)。面向切面编程是Spring框架的核心特性之一,它允许我们把关注点分离,将横切关注点(如日志、事务管理、权限控制等)与...

    AOP学习笔记

    《AOP学习笔记》 在软件开发中,面向切面编程(Aspect-Oriented Programming,简称AOP)是一种重要的编程范式,它旨在提高代码的可读性和可维护性,通过将关注点分离来实现模块化。AOP的核心概念是切面、连接点、...

    spring学习笔记LBY.pdf

    ### Spring学习笔记知识点详解 #### 一、Spring学习模块概览 Spring框架作为一个全面而强大的企业级应用开发框架,其内部包含多个模块,这些模块分别针对不同的应用场景和技术领域进行了优化设计。了解这些模块有...

    Spring学习笔记(13)----动态代理模式分析演示

    在本篇Spring学习笔记中,我们将深入探讨动态代理模式,并结合Spring框架的实现进行分析演示。动态代理模式是Java编程中一种重要的设计模式,它允许我们在不修改原对象代码的情况下,为对象添加额外的功能或行为。...

    Spring学习笔记(15)----使用Spring的注解方式实现AOP

    在本篇Spring学习笔记中,我们将深入探讨如何利用Spring框架的注解方式来实现面向切面编程(AOP)。AOP是一种编程范式,它允许我们定义横切关注点,如日志、事务管理等,然后将这些关注点模块化并插入到应用程序的多...

    spring框架案例学习文档笔记

    ### Spring框架案例学习文档笔记知识点总结 #### 面向抽象编程 - **定义**:面向抽象编程是一种软件设计原则,旨在通过抽象层隔离具体实现细节。这种方式有助于提高代码的可维护性和灵活性。 - **实践**:在Spring...

    SSH笔记-AOP

    - **@AspectJ注解支持**:Spring支持使用@AspectJ注解来声明切面,这种方式更加简洁且易于理解。 5. **基于XML的配置声明切面** 在不使用注解的情况下,可以在Spring的配置文件中通过和元素来声明切面。这种方式...

    aspectjweaver-1.6.8_2-source-release.zip

    AspectJ 提供了一种声明性的方式来定义切面,包括切入点(pointcut)、通知(advice)和织入(weaving)等概念。 切入点是定义切面应用的精确位置,可以是方法调用、异常抛出等事件。通知则是当切入点匹配时执行的...

    Spring AOP 使用笔记

    本笔记主要探讨了如何在Spring应用中使用AOP来实现横切关注点,如日志、事务管理、性能监控等。 首先,理解AOP的基本概念至关重要。AOP的核心是切面(Aspect),它封装了跨越多个对象的行为或责任。切面由两个主要...

Global site tag (gtag.js) - Google Analytics