(一)Aop术语定义
1.通知(advice)
通知定义了切面要做什么工作,即调用的方法,同时定义了什么时候做这些工作,即以下五种类型
(1)前置通知(Before) :在目标方法调用之前执行切面方法
(2)后置通知(After) :在目标方法调用之后执行切面方法,不关心目标方法的返回值以及是否抛出异常,类似于finally
(3)返回通知(After-returning): 在目标方法正常执行不抛出异常的情况下执行切面方法
(4)异常通知(After-throwing) :在目标方法发生异常的情况下执行切面方法
(5)环绕通知(Around) :切面方法包裹了目标方法,在目标方法之前和之后执行自定义的切面方法调用流程。
2.连接点
即可以插入切面方法到应用的正常流程之中的点
3.切点
即通知真正插入应用程序的时机
4.切面
通知和切点组合而成,即定义了做什么,何时做,在哪里做的一个封装类
5.引入
允许我们向现用的类添加新的方法或属性
6.织入
把切面应用到目标对象并创建新的代理对象的过程
Spring支持四种类型的AOP:基于代理的经典SpringAop(配置过于复杂繁琐,淘汰) 纯POJO切面 @AspectJ注解驱动的切面 注入式AspectJ切面(适用于Spring各版本)
(二)切点的写法(通过Aspectj的切点表达式语言定义)
(1)目前支持的切点表达式语言指示器
Aspectj指示器 | 描述 |
arg() | 限制连接点匹配参数为指定类型的执行方法 |
@args() | 限制连接点匹配参数由指定注解标注的执行方法 |
execution() | 用于匹配是连接点的执行方法 |
this() | 限制连接点匹配AOP代理的bean引用为指定类型的类 |
target() | 限制连接点匹配目标对象为指定的类 |
@target() | 限制连接点匹配特定的执行对象、这些对象对应的类要具有指定类型的注解 |
within() | 限制连接点匹配指定的类型 |
@within() | 限制连接点匹配指定注解所标注的类型(当使用spring aop时,方法定义在由指定的注解所标注的类里) |
@annotation | 限定匹配带有指定注解的连接点 |
只有exection()指示器是执行匹配的,其他都是用来限制匹配的
示例
execution(* springtest.perform.perform(..))
* 表示任意返回类型
springtest.perform.perform()表示springtest包下perform类中perform方法,..表示任意参数类型
在java文件配置中,指示器之间用&&,||连接
execution(* springtest.perform.perform(..)) && bean('test')
在xml文件配置中,&& ||用and or 代替
(三)使用注解创建切面
如上所示就是一个注解切面的定义方式,但是要使用上面的切面,还需要在spring中将他配置为一个bean,同时启动spring的自动代理功能,否则要么在spring上下文中没有这个bean,要么
只是作为一个普通的bean,spring不会将其视为切面,也不会为他转换为切面代理
到此上述切面就能正常使用了
(四)使用注解切面给现有类添加新的方法
给现有的类引入新的方法,我个人认为就是给现有类实现新的接口,同时给予他新接口的实现。如现有
表演接口以及他的实现类
此时,我想要给表演者的实现添加计数的功能,及记录他总共表演了多少次,同时又不想改变现有类的结构,此时就可以使用AOP的引用,如有一个新的表演计数接口以及他的实现类
若要讲上述实现类的功能引入到表演者类中,我们可以创建一个引入切面
此时,如果你用instanceof PerformCount 测试perform的实例会发现结果为true,表明,perform的实例实现了performCount接口,引入成功,即
perform也是performCount的实现类,同时调用新接口的方法时,实现是引入的实现类的方法
(五)使用XML配置也能实现上述全部功能