AOP
AOP相关的基础概念
AOP(面向切面编程),简单来说,就是将一些公共或者复用的代码抽离出来,在需要这些公共代码的地方,将这些代码“织入”进去。
1.切面(Aspect)
切入点和通知结合起来就是切面,类似Java里面的一个类声明。
2.连接点(Join Point)
程序执行过程中某个特定的点,通常是一个方法的执行或者异常处理的时候。
3.通知(Advice)
在切面的连接点上执行的动作,包括“before”、“after”、“around”等通知类型。
通知类型
- 前置通知(Before advice):在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。
- 后置通知(After returning advice):在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
- 异常通知(After throwing advice):在方法抛出异常退出时执行的通知。
- 最终通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
- 环绕通知(Around advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。
4.切入点(Point Cut)
说明在哪些地方(方法)执行,一般通过通配、正则表达式来表示,通知和切入点表达式关联,可知道在满足切入点的连接点上运行。
5.目标对象(Target Object)
被一个或多个切面所通知的对象,也被称做被通知(advised)对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个被代理(proxied)对象。
切入点表达式
1.execution
execution表达式可以用于明确指定方法返回类型,类名,方法名和参数名等与方法相关的部件,并且在Spring中,大部分需要使用AOP的业务场景也只需要达到方法级别即可,因而execution表达式的使用是最为广泛的。如下是execution表达式的语法:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
这里问号表示当前项可以有也可以没有,其中各项的语义如下:
- modifiers-pattern:方法的可见性,public、protected等;
- ret-type-pattern:方法返回的类型,void、String等;
- declaring-type-pattern:方法所在类的全路径名,如com.spring.Aspect;
- name-pattern:方法名类型,如buisinessService();
- param-pattern:参数类型,如java.lang.String等;
- throws-pattern:抛出的异常类型,如java.lang.Exception。
如下是一个使用execution表达式的例子:
execution(public * com.demo.Aspect.addLog(java.lang.String,..))
上述切点表达式将会匹配使用public修饰,返回值为任意类型,并且是com.demo.Aspect类中名称为addLog的方法,方法可以有多个参数,但是第一个参数必须是java.lang.String类型的方法。上述示例中我们使用了…通配符,关于通配符的类型,主要有两种:
- *通配符,该通配符主要用于匹配单个单词,或者是以某个词为前缀或后缀的单词。
如下示例表示返回值为任意类型,在com.spring.service.BusinessObject类中,并且参数个数为零的方法:
execution(* com.spring.service.BusinessObject.*())
下述示例表示返回值为任意类型,在com.spring.service包中,以Business为前缀的类,并且是类中参数个数为零方法:
execution(* com.spring.service.Business*.*())
- … (两个点)通配符,该通配符表示0个或多个项,主要用于declaring-type-pattern和param-pattern中,如果用于declaring-type-pattern中,则表示匹配当前包及其子包,如果用于param-pattern中,则表示匹配0个或多个参数。