美文网首页
AOP基础理解

AOP基础理解

作者: 向梦而来 | 来源:发表于2020-11-27 14:56 被阅读0次

    一、基础概念

    AOP 是 Aspect-Oriented programming 的缩写,中文翻译为面向切面编程,它和 OOP 一样是一种编程思想。
    OOP的优点:设计低耦合系统,但增加了代码的重复性,例如,想打印方法的出入日志,就需要在每个方法加上重复的代码,这时候就需要AOP编程思想。
    AOP把系统分为核心关注点和横切关注点,核心关注点只需要负责业务的核心流程,横切关注点与核心业务关系不大,可以抽象出来的公共方法组件,像打印方法的出入日志、对方法加分布式锁、统计接口rt等。如下图所示:


    AOP核心关注点和横切关注点.png

    二、术语

    术语 术语 说明
    连接点 join point 连接点指切面可以织入的一个点,这个点可以是调用方法时,抛出异常时、修改字段时,它是一个抽象的概念,在实现AOP时,不需要定义一个连接点
    切入点 point cut 是指切面具体织入的位置,并不是所有的连接点都需要被织入,切入点时开发者自己选择连接点的方法
    通知 advice 通知是切面的一种实现,可以完成简单织入功能。通知定义了增强代码切入到目标代码的时间点,是目标方法执行之前执行,还是之后执行等。通知类型不同,切入时间不同。
    切面 aspect 切面泛指交叉业务逻辑,是切入点和通知的结合。比如事物处理,日志处理就可以理解为切面。实际就是对主业务逻辑的一种增强
    织入 weaving 是指将切面应用到目标对象(新创建的代理对象)的过程。织入的方式包含:编译期织入、类加载期织入、运行期织入,

    织入: Spring 是通过何种方式将通知织入到目标方法上的。是通过实现后置处理BeanPostProcessor 接口。该接口是 Spring 提供的一个拓展接口,通过实现该接口,用户可在 bean 初始化完成后,即 bean 执行完初始化方法(init-method)。Spring通过切点对 bean 类中的方法进行匹配。若匹配成功,则会为该 bean 生成代理对象,并将代理对象返回给容器。容器向后置处理器输入 bean 对象,得到 bean 对象的代理,这样就完成了织入过程。

    AOP术语如图所示:


    AOP术语.png

    通知类型:

    术语 术语 说明
    前置通知 @Before 在执行目标方法之前运行
    后置通知 @After 在目标方法运行结束之后,不管有没有异常
    返回通知 @AfterReturning 在目标方法正常返回值后运行
    异常通知 @AfterThrowing 在目标方法出现异常后运行
    环绕通知 @Around 目标方法的调用由环绕通知决定,即你可以决定是否调用目标方法,joinPoint.procced()就是执行目标方法的代码 ,环绕通知可以控制返回对象

    三、AOP实现原理

    AOP 是基于 代理模式 和 装饰者模式 实现的。

    代理模式和装饰者模式都是常用的 Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。

    两种模式最主要的区别是:代理模式中,代理类对被代理的对象有控制权,决定其执行或者不执行。而装饰模式中,装饰类对代理对象没有控制权,只能为其增加一层装饰,以加强被装饰对象的功能。

    代理类可以分为两种。

    • 静态代理:由程序员或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的 .class字节码 文件就已经存在。
    • 动态代理:在程序运行时,工具类会动态的生成代理类的 .class字节码 缓存在内存中,再运用反射机制,实例化出代理对象。动态代理有以下几种实现形式:JDK自带的动态代理(常用)、CGLIB(常用)、javaassist字节码操作库实现、ASM(底层使用指令,可维护性较差)。

    四、AOP 的具体实现

    切面织入的方式有3种,分别是:

    • 运行时织入(Runtime wearing):是指采用 jdk代理 或 cglib 工具进行切面的织入。
    • 编译期织入(Compile time wearing):是指在 Java 编译期,采用特殊的编译器,将切面织入到 Java 类中。
    • 类加载期织入(Classload time wearing):是指通过特殊的类加载器,在类字节码加载到 JVM 时织入切面。

    Spring AOP 是采用运行时织入(Runtime wearing),它是基于动态代理的实现的。如果需要代理的对象,实现了某个接口,那么 Spring AOP 会使用 jdk代理 去创建代理对象,而对于没有实现接口的对象,Spring AOP 会使用 cglib 生成一个被代理对象的子类。

    AspectJ 采用编译期织入(Compile time wearing)和类加载期织入(Classload time wearing),它是基于静态代理的实现的。

    相关文章

      网友评论

          本文标题:AOP基础理解

          本文链接:https://www.haomeiwen.com/subject/ifcxwktx.html