5. Spring5源码--Spring AOP源码分析

2020-12-02 14:46:55 浏览数 (1)

目标:

1.什么是AOP, 什么是AspectJ,

2. 什么是Spring AOP

3. Spring AOP注解版实现原理

4. Spring AOP切面原理解析


一. 认识AOP

1.1 什么是AOP

aop是面向切面编程,相比传统oop,aop能够在方法的前置,中置,后置中插入逻辑代码,对于项目中大量逻辑重复的代码,使用aop能很好的收口逻辑,将逻辑独立于业务代码之外,一处编写,多处使用。

AOP是Object Oriented Programming(OOP)的补充.

OOP能够很好地解决对象的数据和封装的问题,却不能很好的解决Aspect("方面")分离的问题。下面举例具体说明。

比如,我们有一个Bank(银行)类。Bank有两个方法,save(存钱)和withdraw(取钱)。

类和方法的定义如下:

代码语言:javascript复制
package com.lxl.www.aop;

public class Bank {

  /**
   * 存钱
   */
  public Float save(Account account, float money) {
    // 增加account账户的钱数,返回账户里当前的钱数
    return null;
  }

  /**
   * 取钱
   */
  public Float withdraw(Account account, float money) {
    // 减少account账户的钱数,返回取出的钱数
    return null;
  }
};

这两个方法涉及到用户的账户资金等重要信息,必须要非常小心,所以编写完上面的商业逻辑之后,项目负责人又提出了新的要求--给Bank类的每个重要方法加上安全认证特性。

于是, 我们在两个方法上增加安全代码

改后的类和方法如下:

代码语言:javascript复制
public class Bank {

  /**
   * 存钱
   */
  public Float save(Account account, float money) {
    // 验证account是否为合法用户
    // 增加account账户的钱数,返回账户里当前的钱数
    return null;
  }

  /**
   * 取钱
   */
  public Float withdraw(Account account, float money) {
    // 验证account是否为合法用户
    // 减少account账户的钱数,返回取出的钱数
    return null;
  }
};

这两个方法都需要操作数据库,为了保持数据完整性,项目负责人又提出了新的要求--给Bank类的每个操作数据库的方法加上事务控制。

于是,我们不得不分别在上面的两个方法中加入安全认证的代码。

类和方法的定义如下:

代码语言:javascript复制
package com.lxl.www.aop;

public class Bank {

  /**
   * 存钱
   */
  public Float save(Account account, float money) {
    // 验证account是否为合法用户
    // begin Transaction
    // 增加account账户的钱数,返回账户里当前的钱数
    // end Transaction
    return null;
  }

  /**
   * 取钱
   */
  public Float withdraw(Account account, float money) {
    // 验证account是否为合法用户
    // begin Transaction
    // 减少account账户的钱数,返回取出的钱数
    // end Transaction 
    return null;
  }
};

我们看到,这些与商业逻辑无关的重复代码遍布在整个程序中。实际的工程项目中涉及到的类和函数,远远不止两个。如何解决这种问题?

AOP就是为了解决这种问题而出现的。在不修改代码的情况下达到增强的效果

1.2 AOP的相关概念

  • 切面(Aspect): 封装通用业务逻辑的组件,即我们想要插入的代码内容. 在spring AOP中, 切面可以使用通用类基于模式的方式, 或者在普通类中标注@Aspect注解来实现
  • 连接点(Join point): 连接点是在应用执行过程中能够插入切面的点。简单理解, 可以理解为需要增强的方法.
  • 通知(Advice): 用于指定具体产生作用的位置,是方法之前或之后等等
    • 前置通知(before) - 在目标方法被调用之前调用通知功能
    • 后置通知(after) - 在目标方法完成之后调用通知(不论程序是否出现异常),此时不会关心方法的输出是什么
    • 返回通知(after-returning) - 在目标方法成功执行之后调用通知
    • 异常通知(after-throwing) - 在目标方法抛出异常后调用通知
    • 环绕通知(around) - 通知包裹了被通知的方法,在被通知的方法调用之前和调用之后执行自定义的行为
  • 目标对象(target): 目标对象是指要被增强的对象, 即包含主业务逻辑的类对象
  • 切点(PointCut): 指定哪些Bean组件的哪些方法使用切面组件. 例如:当执行某个特定名称的方法时.我们定义一个切点(execution com.lxl.www.aop.*.*(..)) . 切点表达式如何和连接点匹配是AOP的核心. spring默认使用AspectJ切点语义.
  • 织入(Weaving):通知切入连接点过程叫做织入
  • 引入(Introductions): 可以将其它接口或者实现动态引入到targetClass中

对照上图, 来对应每一个区域,看看其具体含义

那么在Spring中使用AOP就意味着你需要:

  • 目标程序,某个需要被插入通用代码片段的方法
  • 切面程序,即通用代码,用来插入方法的那些代码片段(无返回类型,参数类型与通知类型有关)
  • 配置文件,用来指定切入点和通知

as

0 人点赞