Spring AOP

一、什么是 AOP 、Spring AOP

1.1 什么是AOP

  1. 地位:Spring两大核心之一,另一个是loC
  2. 什么是AOP:AOP和OOP主要是处理事情的维度不同,都是一种思想,实现方法有很多种
    • AOP:面向切面编程(对某一类特定的问题进行编程)
      • 什么是切面:某一类特定问题
      • 关于统一功能
        • 统一功能处理就是AOP的一个实现,因为拦截器、统一异常等问题就是一个【特定的问题】
        • 也因为只是其中一个实现,统一功能的代码并没有用到@Before、@After之类的注解
      • AOP常见的实现方式:Spring AOP、aspectJ(Spring使用了aspectJ的注解【@Aspect】,但自己进行了实现)
    • OOP:面向对象编程(在进行Java编程时,把图书、人之类的想成一个类)
  3. AOP优点:不修改原始的业务代码就能增加新的功能,提高了开发效率

1.2 什么是Spring AOP

  1. 什么是Spring AOP:AOP是一种思想,实现方式有很多,Spring也实现了AOP,我们把其称为【Spring AOP】
  2. Spring AOP有什么用:可以自定义AOP
    • 为什么需要自定义:有些需求无法被Spring写好的的AOP实例满足
      • Spring针对一些场景的场景,帮我们写了AOP也就是【统一功能】。但就像拦截器的作用维度是URL一样,有时候现有的AOP没有办法完成一些定制化的需求,此时我们就可以借助Spring给我们提供的API,自定义AOP

二、AOP概念

2.1 切点

  1. 什么是切点:表示一组规则,告诉程序目标方法是什么,通过切点表达式来描述
  2. 如何把切点提出来定义
    在这里插入图片描述
  3. 如何在其他切面类中使用这个提出来的切点
    在这里插入图片描述

2.2 切点表达式

  1. 什么切点表达式:如【execution(* com.example.book_test.controller..(…))】
    • 第一个.*:controller包下的所有类
    • 第二个*:该类下的每一个方法
  2. 切点表达式的两种表达方式:匹配得上就执行,匹配不上就不执行
    • execution)(……):通过方法的签名来匹配,更加倾向于具有一定规则的
      在这里插入图片描述

    • @annotation:根据注解匹配,当规则比较难找/难描述的时候,就可以使用注解匹配

      • 实现步骤:
        【1】编写自定义注解
        【2】使用@annotation表达式来描述切点
        【3】在连接点的方法上添加自定义注解
      • 代码实现
        在这里插入图片描述

2.2 连接点

  1. 什么是连接点:切点描述的方法、切面要作用的方法、目标方法,具象为【ProceedingJoinPoint joinPoint】

2.3 通知

  1. 什么是通知:对要处理的一类问题的处理逻辑
  2. 通知类型:注意@Around注解必须要有返回值,其他注解无所谓。如果@Around没有返回结果,那整个方法也没有结果(返回值是joinPoint.proceed()的结果)
    • @Around:环绕通知,该注解标注的通知方法在目标方法前后都被执行
    • @Before:前置通知,该注解标注的通知方法在目标方法前被执行
    • @After:后置通知,该注解标注的通知方法在目标方法后被执行,无论是否有异常都会执行
    • @AfterReturning:返回后通知,该注解标注的通知方法在目标方法后被执行,有异常不会执行
    • @AfterThrowing:异常后通知,该注解标注的通知方法在发生异常后执行
  3. 不同通知类型的执行顺序
    在这里插入图片描述

2.4 切面

  1. 什么是切面:切点 + 通知
    在这里插入图片描述
  2. 切面优先级
    • 为什么会有切面优先级
      在这里插入图片描述

    • 原理
      在这里插入图片描述

    • 如何定义切面优先级
      在这里插入图片描述

三、代码案例:实现打印所有接口执行时间的AOP

  1. 不用AOP,如何打印一个接口的执行时间
long start = System.currentTimeMillis();
long end = System.currentTimeMillis();
System.out.println("执行时间:" + (end - start) + "ms");
  1. 使用AOP操作
    • 为什么可以用AOP:【需要打印每个接口的执行时间】就是一类问题
    • 代码
      • @Aspect:表明这是一个切面类,该注解来自于引入的AOP依赖,但此处只是应用了Aspect(一个第三方包)的注解,真正的实现还是在Spring这里
        • import org.aspectj.lang.annotation.Aspect; 使用了该包里的@Aspect注解,实现不是它
      • @Around:环绕着目标方法执行
      • “execution(* com.example.book_test.controller..(…))”:用表达式来指定哪些是目标方法
        • 该表达式指【对所有在controller层里的代码生效】
      • ProceedingJoinPoint joinPoint:当前作用到的目标方法

在这里插入图片描述

四、Spring AOP 是如何实现的

Spring AOP是基于动态代理来实现的

4.1 代理模式

  1. 分类:分为静态代理模式和动态代理模式
  2. 生活中的代理
    • 如果有人要联系一个公司的老板,需要先由秘书进行代理,由秘书与老板进行沟通
    • 有人要买房子,卖方把房屋授权给中介,由中介来代理买房事宜
  3. 代理的作用:可以在业务实现类提供的功能基础上,增强额外的功能
    • 比如房东可以租房子给我们,但如果是遇到维修之类的问题,房东不会处理,因为房东提供的功能是有限的。而如果有中介这个代理,中介可以在房东提供的功能的基础上,对功能进行增强,比如在房东真的租房前,给我们介绍房子的相关信息,在租房后,给我们进行一些售后服务
  4. 代理的效果
    在这里插入图片描述
  5. 适配器模式 VS 代理模式:适配器模式解决接口不兼容的问题,代理模式则是控制对其他对象的访问
    • 设计模式最根本的区别是设计思想,而非代码实现上的差别

4.2 静态代理

  1. 什么是静态代理:在程序运行前,代理对象就已经对目标对象进行了步骤的预执行代码(通过编译),知道将要执行哪些操作,运行哪些代码
    • 静态:不变了
    • 举例:打扫卫生前,提前安排出一张值日表,在还没有正式打扫前,每个人都知道自己要负责的职位
  2. 代码实现:代码的逻辑都是提前写好的,在编译运行之后,谁去代理谁,去执行什么操作都是确定好了的
    在这里插入图片描述

4.3 动态代理

【1】概念

  1. 什么是动态代理:提前没有代理对象,程序在运行过程中,才会去临时生成一个代理对象并进行代理操作(不需要提前去预知有哪些工作要去做,而是当事情来了之后,再去处理)
    • 为什么要有动态代理:静态代理时,每修改一下业务接口,业务实现类和代理类都需要发生变更,十分繁琐
    • 举例:等到开始打扫时,发现哪块比较脏,就临时安排一个空闲的人去打扫
  2. 常见的两种动态代理的实现方式:Java也对动态代理进行了实现,并提供了一些API,下面是两种常见的实现方式
    • JDK动态代理:可以代理接口,不能代理类
    • CGLIB动态代理:CGLIB是一个第三方的包。类和接口都能代理

【2】JDK动态代理

  1. 实现步骤
    • 定义一个业务接口及其业务实现类
    • 实现InvocationHandler接口,并重写involve方法(这里面)
    • 通过 【Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)】创建代理对象
  2. 代码实现
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  3. JDK动态代理的缺点
    在这里插入图片描述

【3】CGLIB动态代理

  1. 实现步骤
    • 定义一个被代理类
    • 自定义MethodInterceptor,并重写intercept方法(用于增强目标方法,类似于JDK动态代理中的invoke方法)
    • 通过Enhancer类的 create() 创建代理类
  2. 代码编写
    在这里插入图片描述
  3. 可代理对象:类和接口都可以代理

4.4 用原理讲解Spring AOP

在这里插入图片描述

4.5 源码分析

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 17
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值