在看这篇文章前,建议首先看下 Spring aop与AspectJ的区别?

aop是对oop的补充。

参阅:https://blog.csdn.net/column/details/aspectj.html

除了aspecj还有那些常用的Aop,以及他们的区别

  • Jboss Aop:我基本上没有用过,所以没有发言权
  • Spring Aop:Spring自己原生的Aop,只能用一个词来形容:难用。 你需要实现大量的接口,继承大量的类,所以spring aop一度被千夫所指。这于他的无侵入,低耦合完全冲突。不过Spring对开源的优秀框架,组建向来是采用兼容,并入的态度。所以,后来的Spring 就提供了Aspectj支持,也就是我们后来所说的基于纯POJO的Aop。

   区别:Spring Aop采用的动态织入,而Aspectj是静态织入。静态织入:指在编译时期就织入,即:编译出来的class文件,字节码就已经被织入了。动态织入又分静动两种,静则指织入过程只在第一次调用时执行;动则指根据代码动态运行的中间状态来决定如何操作,每次调用Target的时候都执行。有不清楚的同学,可以自己补下基础的代理知识。

一、aop在aspectj中由哪些组件组成?

pointcut(切点):是一个(组)基于正则表达式的表达式,有点绕,就是说他本身是一个表达式,但是他是基于正则语法的。通常一个pointcut,会选取程序中的某些我们感兴趣的执行点,或者说是程序执行点的集合。

   joinPoint(连接点): 通过pointcut选取出来的集合中的具体的一个执行点,我们就叫JoinPoint.

   Advice(通知): 在选取出来的JoinPoint上要执行的操作、逻辑。关于5种类型,我不多说(before、after、afterreturn、afterthrowing、round),不懂的同学自己补基础。

   aspect(切面): 就是我们关注点的模块化。这个关注点可能会横切多个对象和模块,事务管理是横切关注点的很好的例子。它是一个抽象的概念,从软件的角度来说是指在应用程序不同模块中的某一个领域或方面。又pointcut 和  advice组成。

   Target:被aspectj横切的对象。我们所说的joinPoint就是Target的某一行,如方法开始执行的地方、方法类调用某个其他方法的代码。

二、Spring AOP支持的AspectJ切入点指示符

切入点指示符用来指示切入点表达式目的,在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指示符如下:

execution:用于匹配方法执行的连接点;

within:用于匹配指定类型内的方法执行;

this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配;

target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;

args:用于匹配当前执行的方法传入的参数为指定类型的执行方法;

@within:用于匹配所以持有指定注解类型内的方法;

@target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;

@args:用于匹配当前执行的方法传入的参数持有指定注解的执行;

@annotation:用于匹配当前执行方法持有指定注解的方法;

bean:Spring AOP扩展的,AspectJ没有对于指示符,用于匹配特定名称的Bean对象的执行方法;

reference pointcut:表示引用其他命名切入点,只有@ApectJ风格支持,Schema风格不支持。

AspectJ切入点支持的切入点指示符还有: call、get、set、preinitialization、staticinitialization、initialization、handler、adviceexecution、withincode、cflow、cflowbelow、if、@this、@withincode;但Spring AOP目前不支持这些指示符,使用这些指示符将抛出IllegalArgumentException异常。这些指示符Spring AOP可能会在以后进行扩展。

三、命名及匿名切入点

命名切入点可以被其他切入点引用,而匿名切入点是不可以的。只有@AspectJ支持命名切入点,而Schema风格不支持命名切入点。如下所示,@AspectJ使用如下方式引用命名切入点:

四、类型匹配语法

首先让我们来了解下AspectJ类型匹配的通配符:

*:匹配任何数量字符;

..:匹配任何数量字符的重复,如在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。

+:匹配指定类型的子类型;仅能作为后缀放在类型模式后边。

java.lang.String    匹配String类型;
java.*.String 匹配java包下的任何“一级子包”下的String类型;
如匹配java.lang.String,但不匹配java.lang.ss.String
java..* 匹配java包及任何子包下的任何类型;
如匹配java.lang.String、java.lang.annotation.Annotation
java.lang.*ing 匹配任何java.lang包下的以ing结尾的类型;
java.lang.Number+ 匹配java.lang包下的任何Number的自类型;
如匹配java.lang.Integer,也匹配java.math.BigInteger

五、组合切入点表达式

AspectJ使用 且(&&)、或(||)、非(!)来组合切入点表达式。

在Schema风格下,由于在XML中使用“&&”需要使用转义字符“&&”来代替之,所以很不方便,因此Spring ASP 提供了and、or、not来代替&&、||、!。

六、切入点使用示例

1、execution:使用“execution(方法表达式)”匹配方法执行;

模式

描述

public * *(..)

任何公共方法的执行

* cn.javass..IPointcutService.*()

cn.javass包及所有子包下IPointcutService接口中的任何无参方法

* cn.javass..*.*(..)

cn.javass包及所有子包下任何类的任何方法

* cn.javass..IPointcutService.*(*)

cn.javass包及所有子包下IPointcutService接口的任何只有一个参数方法

* (!cn.javass..IPointcutService+).*(..)

非“cn.javass包及所有子包下IPointcutService接口及子类型”的任何方法

* cn.javass..IPointcutService+.*()

cn.javass包及所有子包下IPointcutService接口及子类型的的任何无参方法

* cn.javass..IPointcut*.test*(java.util.Date)

cn.javass包及所有子包下IPointcut前缀类型的的以test开头的只有一个参数类型为java.util.Date的方法,注意该匹配是根据方法签名的参数类型进行匹配的,而不是根据执行时传入的参数类型决定的

如定义方法:public void test(Object obj);即使执行时传入java.util.Date,也不会匹配的;

* cn.javass..IPointcut*.test*(..)  throws

IllegalArgumentException, ArrayIndexOutOfBoundsException

cn.javass包及所有子包下IPointcut前缀类型的的任何方法,且抛出IllegalArgumentException和ArrayIndexOutOfBoundsException异常

* (cn.javass..IPointcutService+

&& java.io.Serializable+).*(..)

任何实现了cn.javass包及所有子包下IPointcutService接口和java.io.Serializable接口的类型的任何方法

@java.lang.Deprecated * *(..)

任何持有@java.lang.Deprecated注解的方法

@java.lang.Deprecated @cn.javass..Secure  * *(..)

任何持有@java.lang.Deprecated和@cn.javass..Secure注解的方法

@(java.lang.Deprecated || cn.javass..Secure) * *(..)

任何持有@java.lang.Deprecated或@ cn.javass..Secure注解的方法

(@cn.javass..Secure  *)  *(..)

任何返回值类型持有@cn.javass..Secure的方法

*  (@cn.javass..Secure *).*(..)

任何定义方法的类型持有@cn.javass..Secure的方法

* *(@cn.javass..Secure (*) , @cn.javass..Secure (*))

任何签名带有两个参数的方法,且这个两个参数都被@ Secure标记了,

如public void test(@Secure String str1,

@Secure String str1);

* *((@ cn.javass..Secure *))或

* *(@ cn.javass..Secure *)

任何带有一个参数的方法,且该参数类型持有@ cn.javass..Secure;

如public void test(Model model);且Model类上持有@Secure注解

* *(

@cn.javass..Secure (@cn.javass..Secure *) ,

@ cn.javass..Secure (@cn.javass..Secure *))

任何带有两个参数的方法,且这两个参数都被@ cn.javass..Secure标记了;且这两个参数的类型上都持有@ cn.javass..Secure;

* *(

java.util.Map<cn.javass..Model, cn.javass..Model>

, ..)

任何带有一个java.util.Map参数的方法,且该参数类型是以< cn.javass..Model, cn.javass..Model >为泛型参数;注意只匹配第一个参数为java.util.Map,不包括子类型;

如public void test(HashMap<Model, Model> map, String str);将不匹配,必须使用“* *(

java.util.HashMap<cn.javass..Model,cn.javass..Model>

, ..)”进行匹配;

而public void test(Map map, int i);也将不匹配,因为泛型参数不匹配

* *(java.util.Collection<@cn.javass..Secure *>)

任何带有一个参数(类型为java.util.Collection)的方法,且该参数类型是有一个泛型参数,该泛型参数类型上持有@cn.javass..Secure注解;

如public void test(Collection<Model> collection);Model类型上持有@cn.javass..Secure

* *(java.util.Set<? extends HashMap>)

任何带有一个参数的方法,且传入的参数类型是有一个泛型参数,该泛型参数类型继承与HashMap;

Spring AOP目前测试不能正常工作

* *(java.util.List<? super HashMap>)

任何带有一个参数的方法,且传入的参数类型是有一个泛型参数,该泛型参数类型是HashMap的基类型;如public voi test(Map map);

Spring AOP目前测试不能正常工作

* *(*<@cn.javass..Secure *>)

任何带有一个参数的方法,且该参数类型是有一个泛型参数,该泛型参数类型上持有@cn.javass..Secure注解;

Spring AOP目前测试不能正常工作

2、within:使用“within(类型表达式)匹配指定类型内的方法执行;

模式

描述

within(cn.javass..*)

cn.javass包及子包下的任何方法执行

within(cn.javass..IPointcutService+)

cn.javass包或所有子包下IPointcutService类型及子类型的任何方法

within(@cn.javass..Secure *)

持有cn.javass..Secure注解的任何类型的任何方法

必须是在目标对象上声明这个注解,在接口上声明的对它不起作用

 

3、this:使用“this(类型全限定名)”匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口方法也可以匹配;注意this中使用的表达式必须是类型全限定名,不支持通配符;

 

模式

描述

this(cn.javass.spring.chapter6.service.IPointcutService)

当前AOP对象实现了 IPointcutService接口的任何方法

this(cn.javass.spring.chapter6.service.IIntroductionService)

当前AOP对象实现了 IIntroductionService接口的任何方法

也可能是引入接口

 

4、target使用“target(类型全限定名)”匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;注意target中使用的表达式必须是类型全限定名,不支持通配符;

模式

描述

target(cn.javass.spring.chapter6.service.IPointcutService)

当前目标对象(非AOP对象)实现了 IPointcutService接口的任何方法

target(cn.javass.spring.chapter6.service.IIntroductionService)

当前目标对象(非AOP对象) 实现了IIntroductionService 接口的任何方法

不可能是引入接口

 

5、args使用“args(参数类型列表)”匹配当前执行的方法传入的参数为指定类型的执行方法;注意是匹配传入的参数类型,不是匹配方法签名的参数类型;参数类型列表中的参数必须是类型全限定名,通配符不支持;args属于动态切入点,这种切入点开销非常大,非特殊情况最好不要使用;

模式

描述

args (java.io.Serializable,..)

任何一个以接受“传入参数类型为 java.io.Serializable” 开头,且其后可跟任意个任意类型的参数的方法执行,args指定的参数类型是在运行时动态匹配的

 

6、@within:使用“@within(注解类型)”匹配所以持有指定注解类型内的方法;注解类型也必须是全限定类型名;

模式

描述

@within cn.javass.spring.chapter6.Secure)

任何目标对象对应的类型持有Secure注解的类方法;

必须是在目标对象上声明这个注解,在接口上声明的对它不起作用

 

7、@target:使用“@target(注解类型)”匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;注解类型也必须是全限定类型名;

 

模式

描述

@target (cn.javass.spring.chapter6.Secure)

任何目标对象持有Secure注解的类方法;

必须是在目标对象上声明这个注解,在接口上声明的对它不起作用

 

8、@args:使用“@args(注解列表)”匹配当前执行的方法传入的参数持有指定注解的执行;注解类型也必须是全限定类型名;

模式

描述

@args (cn.javass.spring.chapter6.Secure)

任何一个只接受一个参数的方法,且方法运行时传入的参数持有注解 cn.javass.spring.chapter6.Secure;动态切入点,类似于arg指示符;

 

9、@annotation:使用“@annotation(注解类型)”匹配当前执行方法持有指定注解的方法;注解类型也必须是全限定类型名;

模式

描述

@annotation(cn.javass.spring.chapter6.Secure )

当前执行方法上持有注解 cn.javass.spring.chapter6.Secure将被匹配

 

10、bean:使用“bean(Bean id或名字通配符)”匹配特定名称的Bean对象的执行方法;Spring ASP扩展的,在AspectJ中无相应概念;

模式

描述

bean(*Service)

匹配所有以Service命名(id或name)结尾的Bean

 

11、reference pointcut表示引用其他命名切入点,只有@ApectJ风格支持,Schema风格不支持,如下所示:

 

六、spring aspectj与自定义注解结合使用

https://www.cnblogs.com/magicalSam/p/7161942.html

AspectJ切入点语法详解的更多相关文章

  1. spring AspectJ切入点语法详解 记录以便查阅

    AspectJ切入点语法详解 6.5.1  Spring AOP支持的AspectJ切入点指示符 切入点指示符用来指示切入点表达式目的,,在Spring AOP中目前只有执行方法这一个连接点,Spri ...

  2. 开涛spring3(6.5) - AOP 之 6.5 AspectJ切入点语法详解

    6.5.1  Spring AOP支持的AspectJ切入点指示符 切入点指示符用来指示切入点表达式目的,,在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的Aspect ...

  3. Spring AspectJ切入点语法详解

    1.Spring AOP支持的AspectJ切入点指示符 切入点指示符用来指示切入点表达式目的,,在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指 ...

  4. Spring的AOP AspectJ切入点语法详解(转)

    一.Spring AOP支持的AspectJ切入点指示符 切入点指示符用来指示切入点表达式目的,在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指示 ...

  5. Spring AspectJ 切入点语法详解(7)

    1.Spring AOP支持的AspectJ切入点指示符 切入点指示符用来指示切入点表达式目的,,在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指 ...

  6. Spring 之AOP AspectJ切入点语法详解

    记录一下,以后学习 https://blog.csdn.net/zhengchao1991/article/details/53391244

  7. spring AOP 之四:@AspectJ切入点标识符语法详解

    @AspectJ相关文章 <spring AOP 之二:@AspectJ注解的3种配置> <spring AOP 之三:使用@AspectJ定义切入点> <spring ...

  8. Velocity魔法堂系列二:VTL语法详解

    一.前言 Velocity作为历史悠久的模板引擎不单单可以替代JSP作为Java Web的服务端网页模板引擎,而且可以作为普通文本的模板引擎来增强服务端程序文本处理能力.而且Velocity被移植到不 ...

  9. Hive笔记--sql语法详解及JavaAPI

    Hive SQL 语法详解:http://blog.csdn.net/hguisu/article/details/7256833Hive SQL 学习笔记(常用):http://blog.sina. ...

随机推荐

  1. MTK 快速开机 技术详解

    Android version 2.3.5 首先查看Settings里控制开关 01 // 获取当前状态 02 boolean ipoSettingEnabled = Settings.System. ...

  2. Smali语法汇总(二)

    Opcode 操作码(hex) Opcode name 操作码名称 Explanation 说明 Example 示例 0F return vx 返回在vx寄存器的值. 0F00 - return v ...

  3. HBase数据字典

    数据字典用来存储了系统的元数据.HBase的元数据包括:用户表的定义.表的切分方案.分片的分布情况(即分片分布在哪个regionserver上).分片对应的数据文件和日志文件.其中,分片和数据文件的映 ...

  4. Java语言实现二分法

    二分法是一个简单,高效,并广泛应用的查找方法 import java.util.arrays; public class BinarySearch { public static int rank(i ...

  5. SharePoint 入门级介绍

    前言:接触SharePoint两年有余,从一开始的小白,变成现在的菜鸟,一路走来,学到很多,现在,想把自己知道的东西,写给大家,尤其是刚刚接触SharePoint的人们,做一个简单的参考.从一开始接触 ...

  6. 网络最短路径Dijkstra算法

    最近在学习算法,看到有人写过的这样一个算法,我决定摘抄过来作为我的学习笔记: <span style="font-size:18px;">/* * File: shor ...

  7. LeetCode(69)-Reverse String

    题目: Write a function that takes a string as input and returns the string reversed. Example: Given s ...

  8. ruby中如何调用与局部变量同名的私有方法

    如果ruby中一个局部变量名和私有方法名同名的话,默认该名称被解释为变量而不是方法: x=10; def x;puts "what?" end 当你输入x实际不能执行x方法.解释器 ...

  9. python下实现二叉堆以及堆排序

    python下实现二叉堆以及堆排序 堆是一种特殊的树形结构, 堆中的数据存储满足一定的堆序.堆排序是一种选择排序, 其算法复杂度, 时间复杂度相对于其他的排序算法都有很大的优势. 堆分为大头堆和小头堆 ...

  10. js定义数组的方法

    1.定义时赋值 var mycars=new Array("a","b","c") 2.new一个数组对象 var mycars=new A ...