10、Spring之AOP概述
10.1、概念
-
AOP(Aspect Oriented Programming)是一种设计思想,是软件设计领域中的面向切面编程
-
AOP是面向对象编程(OOP)的一种补充和完善,OOP是纵向继承机制,AOP是横向抽取机制
-
AOP能通过预编译方式和运行期动态代理方式,实现在不修改源代码的情况下动态地为程序添加统一的附加功能
10.2、术语
10.2.1、横切关注点
横切关注点是从目标方法中抽取出来的非核心业务代码,一个目标方法中可以有多个横切关注点
public int add(int i, int j) {
//输出日志属于非核心业务,这是该目标方法的第1个横切关注点
System.out.println("[日志] add 方法开始了,参数是:" + i + "," + j);
int result = i + j;
System.out.println("方法内部 result = " + result);
//输出日志属于非核心业务,这是该目标方法的第2个横切关注点
System.out.println("[日志] add 方法结束了,结果是:" + result);
return result;
}
10.2.2、通知
非核心业务代码在目标方法中叫横切关注点,其被抽取封装到一个类(切面类)的方法中,这样的方法就是通知方法
通知方法一共有五种类型:
-
前置通知:在被代理的目标方法前执行
-
返回通知:在被代理的目标方法成功结束后执行(寿终正寝)
-
异常通知:在被代理的目标方法异常结束后执行(死于非命)
-
后置通知:在被代理的目标方法最终结束后执行(盖棺定论)
-
环绕通知:包括上面四种通知对应的所有位置
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
try {
//前置通知增强位置:在调用目标对象执行功能之前,加入额外的操作
System.out.println("[日志] "+method.getName()+" 方法开始了,参数是:" + Arrays.toString(args));
//调用目标对象实现的核心逻辑
result = method.invoke(target, args);
//返回通知增强位置:在调用目标对象执行功能之后,加入额外的操作)
System.out.println("[日志] "+method.getName()+" 方法结束了,结果是:" + result);
} catch (Exception e) {
//异常通知增强位置:在调用目标对象执行功能发生异常时,加入额外的操作
System.out.println("[日志] "+method.getName()+",异常:"+e.getMessage());
} finally {
//后置通知增强位置:在调用目标对象执行功能完毕时,加入额外的操作
System.out.println("[日志] "+method.getName()+",方法执行完毕");
}
//保证代理对象和目标对象的返回值一致
return result;
}
10.2.3、切面
切面是封装通知方法(横切关注点)的类,也叫切面类
10.2.4、目标
目标是被代理的(目标)对象,也就是要进行功能增强的对象,也可以说是要被抽取非核心业务代码的对象
10.2.5、代理
代理是对目标对象进行功能增强的(代理)对象,这个(代理)对象会由AOP通过代理模式自动创建
10.2.6、连接点
连接点是抽取横切关注点的位置
10.2.7、切入点
切入点是一个表达式,可以定位出连接点,从而实现把切面类中的通知方法安插到该位置
10.3、作用
-
简化代码:把方法中固定位置的重复代码抽取出来,让被抽取非核心业务代码的方法更专注于自己的核心功能,从而提高内聚性
-
代码增强:把特定的功能封装到切面类中,哪里有需要就往哪里安插,被安插了切面类特定功能的方法就被切面给增强了