简介
之前我们介绍了字节码增强的一些实现,如果想在业务代码中处理一些具有横切性质的系统级服务,如日志收集、事务管理、安全检查、缓存、对象池管理等时,开发人员需要深入研究字节码相关技术,编写业务代码时编写大量字节码重复相关逻辑,后续更不好维护。
面向切面的编程(Aspect-Oriented Programming,AOP) 是一种编程范式,旨在通过允许横切关注点的分离,提高模块化。AOP要实现的是在我们写的代码的基础上进行一定的包装,如在方法执行前、或执行后、或是在执行中出现异常后这些地方进行拦截处理或叫做增强处理。 AOP允许开发者将横切关注点(跨越多个模块的共同逻辑)与主要业务逻辑分离,以便更有效地管理和重用切面逻辑。AOP最早是AOP联盟的组织提出的,指定的一套规范。在AOP中,两个主要的实现框架是AspectJ和Spring AOP。本文将介绍AOP的概念,深入探讨AspectJ和Spring AOP,以及通过实例演示这两者的应用。
Aop的概念
- 连接点(Jointpoint) :表示需要在程序中插入横切关注点的扩展点,连接点可能是类初始化、方法执行、方法调用、字段调用或处理异常等等,Spring只支持方法执行连接点,在AOP中表示为在哪里干;
- 切入点(Pointcut) : 选择一组相关连接点的模式,即可以认为连接点的集合,Spring支持perl5正则表达式和AspectJ切入点模式,Spring默认使用AspectJ语法,在AOP中表示为在哪里干的集合;
- 通知(Advice) :在连接点上执行的行为,通知提供了在AOP中需要在切入点所选择的连接点处进行扩展现有行为的手段;包括前置通知(before advice)、后置通知(after advice)、环绕通知(around advice),在Spring中通过代理模式实现AOP,并通过拦截器模式以环绕连接点的拦截器链织入通知;在AOP中表示为干什么;
- 方面/切面(Aspect) :横切关注点的模块化,比如上边提到的日志组件。可以认为是通知、引入和切入点的组合;在Spring中可以使用Schema和@AspectJ方式进行组织实现;在AOP中表示为在哪干和干什么集合;
- 引入(inter-type declaration) :也称为内部类型声明,为已有的类添加额外新的字段或方法,Spring允许引入新的接口(必须对应一个实现)到所有被代理对象(目标对象), 在AOP中表示为干什么(引入什么) ;
- 目标对象(Target Object) :需要被织入横切关注点的对象,即该对象是切入点选择的对象,需要被通知的对象,从而也可称为被通知对象;由于Spring AOP 通过代理模式实现,从而这个对象永远是被代理对象,在AOP中表示为对谁干;
- 织入(Weaving) :把切面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。这些可以在编译时(例如使用AspectJ编译器),类加载时和运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。在AOP中表示为怎么实现的;
- AOP代理(AOP Proxy) :AOP框架使用代理模式创建的对象,从而实现在连接点处插入通知(即应用切面),就是通过代理来对目标对象应用切面。在Spring中,AOP代理可以用JDK动态代理或CGLIB代理实现,而通过拦截器模型应用切面。在AOP中表示为怎么实现的一种典型方式;
我们把这些术语串联到一起,方便理解