AOP术语
如果要重用通用功能的话,常见的面向对象技术是继承或委托,但是如果在整个应用中都是用相同的基类,继承往往会导致一个脆弱的体系,而使用委托则有比较复杂的调用
切面,就是将关注的功能模块化为特殊的类,这类就是切面。
通知Advice: 切面中具体要做的事情,分为前置、后置、返回、异常、环绕通知。
连接点(Joint point): 执行过程中能够插入切面的一个点。
切点(Pointcur):如果说通知定义了切面具体做的事情,那么切点具体定义了在何处。切点匹配到所要织入的一个或多个连接点。
切面(Aspect): 在哪里,做什么事情,就是切点+通知
引入(Introduction): 在不改变现有的类的情况下,给现有的类添加新方法和属性。
织入(Weaving): 将切面应用到目标对象并创建新的代理对象的过程。创建代理对象的方式,jdk代理和cglib代理
,一般在三种情况下进行织入:
* 编译期 和 类加载期实现:需要特定的编译器和类加载器
* 运行期:这种是Spring AOP实现方式。
Spring提供了4种类型的AOP支持
* 基于代理的经典Spring AOP
* 纯pojo切面
* @AspectJ注解驱动的切面
* 注入式Aspect切面(适合Spring各版本)
前面三种都是Spring AOP实现的变体,Spring AOP构建在动态代理基础上,Spring对AOP的支持仅限于方法拦截
通过切点来选择连接点
切点用于准确定位在什么地方应用切面的通知。在Spring AOP中,要使用AspectJ的切点表达式语言来定义切点。
AspectJ指示器 | 描述 |
arg() | 限制连接点匹配参数为指定类型的执行方法 |
@args() | 限制连接点匹配参数有指定注解标注的执行方法 |
execution() | 用于匹配是连接点的执行方法 |
this() | 限制连接点匹配AOP代理的bean引用为指定类型的类 |
target() | 限制连接点匹配目标对象为指定类型的类 |
@target | 限制连接点匹配特定的执行对象,这些对象对应的类要具有执行类型的注解 |
within() | 限制连接点匹配指定的类型 |
@within() | 限制连接点匹配指定注解所标注的类型 |
@annotation | 限定匹配带有指定注解的连接点 |
这上面的Spring支持的指示器中,只有execution指示器是实际执行匹配的(编写切点时候最主要指示器),其他的指示器都是用来限制匹配的。
编写切点
package com.bing.proxy;
public interface UserService {
void sayAdd();
}
这个接口存在多个实现类,假设编写UserService在sayAdd()方法执行时候触发通知,使用AspectJ表达式来定义切点:
execution语法结构:
execution(方法修饰符 方法返回值 方法所属类 匹配方法名 (方法中的形参表)方法申明抛出的异常)