**
1、什么是AOP?
**
在单体架构下的软件开发中,一个大型项目通常是依照功能拆分成各个模块。但是如日志、安全和事务管理此类重要且繁琐的开发却没有必要参与到各个模块中,将这些功能与业务逻辑相关的模块分离就是面向切面编程所要解决的问题
AOP采取的是横向抽取机制,取代了传统纵向继承体系重复性代码。
**
2、那么何为软件的横向和纵向?
**
从纵向结构来看就是我们软件的各个模块,它所负责的是软件的核心业务(如购商品购买、添加购物车等);从横向来看的话,软件的各个模块之间又有所关联,其中会包含一些公共模块(例如日志、权限等);这些公共模块可以存在于各个核心业务中,而AOP的处理将两者分离,使开发人员可以专注于核心业务的开发,提高了开发效率。
3、AOP 的作用及优势
作用: 在程序运行期间,不修改源码对已有方法进行增强。
优势: 减少重复代码 提高开发效率 维护方便
4、AOP底层原理
使用动态代理实现
(1)基于JDK的代理
适用于有接口情况,使用动态代理创建接口实现类代理对象
(2)基于CGLIB动态代理
适用于没有接口情况,使用动态代理创建类的子类代理对象
**
5、AOP术语
**
- Advice (通知/增强): 所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。
- Joinpoint (连接点): 所谓连接点是指那些被拦截到的点。在Spring 中,这些点指的是方法,因为Spring 只支持方法类型的 连接点。
- Pointcut (切入点):所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。
- Introduction (引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类动态地添加一些方 法或 Field。
- Target(目标对象): 代理的目标对象。 Weaving (织入): 是指把增强应用到目标对象来创建新的代理对象的过程。
- Spring采用动态代理织入,而 AspectJ 采用编译期织入和类装载期织入。 Proxy(代理): 一个类被 AOP织入增强后,就产生一个结果代理类。 Aspec t(切面): 是切入点和通知(引介)的结合。
**
6、Spring中基于 xml 的 AOP 配置步骤
**
1.把通知 Bean 也交给 Spring 来管理
2.使用 aop : config 标签来表明开始 AOP 的设置
3.使用 aop : aspect 标签配置切面
- id 属性:是给切面提供一个唯一标识
- ref 属性:是指定通知类 Bean 的 id
4.在 aop : aspect 标签的内部使用对应标签来配置通知的类型
-
aop : before 标识前置通知
- method 属性:用于指定类中哪个放啊是前置通知
- pointcut 属性:用于指定切入点表达式,该切入点表达式指的是对业务层中哪些方法增强
-
切入点表达式的写法:
-
关键字:execution ( 表达式 )
-
表达式:
- 标准写法:访问修饰符 + 返回值 + 包名.类名.方法名(参数列表)
- 举例:public void com.greyson.service.impl.IAccountServiceImpl.saveAccount ( )
-
-
全通配写法:* * ….(…)
- 访问修饰符可以省略
- 返回值可以使用通配符,表示任意返回值
- 包名可以使用通配符,表示任意包,但是有几级包就需要写几个 *.
- 包名可以使用… 表示当前包和子包
- 类名和方法名都可以使用 * 来实现通配
- 参数列表:
- 可以直接使写数据类型:
- 基本类型直接写名称(如 int )
- 引用类型写包名.类名的方式 (如 java.lang.String )
- 可以使用通配符表四任意类型,但是必须有参数
- 可以使用 … 表示有无参数即可,有参数可以是任意类型
- 可以直接使写数据类型:
-
实际开发中切入点表达式的通常写法:
- 切到业务层类实现下的所有方法:* com.greyson.service.impl..(…)
-
配置切入点表达式(aop : pointcut):
- id属性用于指定表达式的唯一标识,expression属性用于指定表达式内容
- 此标签写在 aop : aspect标签内部只能当前切面使用,在其外部则所有切面可用
5.Spring常用通知类型
- 前置通知(aop : before):在切入点方法执行之前执行
- 后置通知(aop :after-returning):在切入点方法正常执行之后执行,它和异常通知永远只能执行一个
- 异常通知(aop :after-throwing):在切入点方法执行产生异常之后执行,它和后置通知永远只能执行一个
- 最终通知(aop :after):无论切入点方法是否正常执行它都会在其后面执行
- 环绕通知