Spring(二)

视频链接:https://www.bilibili.com/video/BV1q94y1o7ts?vd_source=9545770e4a2968c05878ffac8589ec6c
视频选集:P39— P76

文章目录

  • 1.AOP面向切面编程
    • 1.1 手写AOP框架
    • 1.2 Spring 原生AOP的通知【切面】
    • 1.3 AOP常用术语
  • 2.AspectJ框架
    • 2.1 基础概念
    • 2.2 AspectJ前置通知@Before
    • 2.3 切入点表达式的各种用法
    • 2.4 AspectJ框架切换JDK动态代理和CGLib动态代理
    • 2.5 前置通知注解方式实现
    • 2.6 前置通知方法参数JoinPoint解析
    • 2.7 @AfterReturning后置通知-注解有returning属性
    • 2.8 环绕通知@Around
    • 2.9 最终通知@After
    • 2.10 定义切入点别名 @Pointcut

1.AOP面向切面编程

AOP ( Aspect Orient Programming),面向切面编程。面向切面编程是从动态角度考虑程序运行过程。AOP底层,就是采用动态代理模式实现的。采用了两种代理:JDK的动态代理,与CGLIB的动态代理。

切面:公共的,通用的,重复的功能称为切面,面向切面编程就是将切面提取出来,单独开发,在需要调用的方法中通过动态代理的方式进行织入。

1.1 手写AOP框架

业务:图书购买业务
切面:事务

  1. 第一个版本:业务和切面紧耦合在一起,没有拆分
  2. 第二个版本:使用子类代理的方式拆分业务和切面
  3. 第三个版本:使用静态代理拆分业务和切面,业务和业务接口已拆分,此时切面紧耦合在业务中
  4. 第四个版本:使用静态代理拆分业务和业务接口,切面和切面接口
  5. 第五个版本:使用动态代理完成第四个版本的优化

创建新module:
Spring(二)_第1张图片
Spring(二)_第2张图片
然后对目录框架和pom.xml进行修改

  • 第一个版本

Spring(二)_第3张图片

  • 第二个版本
    父类:
    Spring(二)_第4张图片
    子类:
    Spring(二)_第5张图片
    测试:
    Spring(二)_第6张图片

  • 第三个版本
    定义接口:
    Spring(二)_第7张图片
    实现接口功能:
    Spring(二)_第8张图片
    静态代理对象:
    Spring(二)_第9张图片
    测试:
    Spring(二)_第10张图片
    添加商品购买业务:

Spring(二)_第11张图片
测试:
Spring(二)_第12张图片

  • 第四个版本
    当需要将切面中的事务变为日志,权限验证等等的时候,就需要进行改变
    Spring(二)_第13张图片
    将上面的三个复制:
    在这里插入图片描述
    创建AOP接口:【default默认实现,在实现的时候不需要全都必须实现】
    Spring(二)_第14张图片
    日志输出实现:

Spring(二)_第15张图片
事务切面实现:

Spring(二)_第16张图片
代理对象:
Spring(二)_第17张图片
测试:
Spring(二)_第18张图片
Spring(二)_第19张图片
当切入多个切面的功能
Spring(二)_第20张图片

  • 第五个版本【动态代理改造】
    先将上面的六个粘贴:
    Spring(二)_第21张图片
    定义代理对象:

Spring(二)_第22张图片
测试:
Spring(二)_第23张图片
在service中增加业务

Spring(二)_第24张图片

Spring(二)_第25张图片
测试:
Spring(二)_第26张图片
在这里插入图片描述

1.2 Spring 原生AOP的通知【切面】

理论概念:
在这里插入图片描述
Spring 原生AOP代码实现:
业务接口:
Spring(二)_第27张图片
业务实现:
Spring(二)_第28张图片
测试:
Spring(二)_第29张图片
Spring(二)_第30张图片
日志切面:
Spring(二)_第31张图片
绑定在一起的原因:在.xml中进行绑定,不需要定义代理了
Spring(二)_第32张图片
注意:底层调用的依然是Proxy.newProxyInstance

1.3 AOP常用术语

  • 切面:就是那些重复的,公共的,通用的功能称为切面,例如:日志,事务,权限.
  • 连接点:就是目标方法.因为在目标方法中要实现目标方法的功能和切面功能.
  • 切入点(Pointcut):指定切入的位置,多个连接点构成切入点.切入点可以是一个目标方法,可以是一个类中的所有方法,可以是某个包下的所有类中的方法.
  • 目标对象:操作谁,谁就是目标对象.
  • 通知(Advice):来指定切入的时机.是在目标方法执行前还是执行后还是出错时,还是环绕目标方法切入切面功能.

2.AspectJ框架

AspectJ是一个优秀面向切面的框架,它扩展了Java 语言,提供了强大的切面实现。它因为是基于java语言开发的,所以无缝扩展.easy to learn and use(易学易用).

2.1 基础概念

AspectJ常见通知类型:

  • 1)前置通知@Before
  • 2)后置通知@AfterReturning
  • 3)环绕通知@Around
  • 4)最终通知@After
  • 5)定义切入点@Pointcut (了解)

AspectJ的切入点表达式(掌握):

规范公式:
在这里插入图片描述

简化后的公式:
在这里插入图片描述
用到的符号:
* 代码
举例:

在这里插入图片描述

2.2 AspectJ前置通知@Before

在目标方法执行前切入切面功能.在切面方法中不可以获得目标方法的返回值,只能得到目标方法的签名

实现的步骤:

  1. 创建业务接口
  2. 创建业务实现
  3. 创建切面类,实现方法
  4. 在applicationContext.xml文件中进行切面绑定
    Spring(二)_第33张图片
    先搭建项目+修改目录+修改pom.xml文件

Spring(二)_第34张图片
Spring(二)_第35张图片

  • 创建业务接口
    Spring(二)_第36张图片
  • 实现业务功能
    Spring(二)_第37张图片
  • 创建切面类
    Spring(二)_第38张图片
  • 切面绑定
    Spring(二)_第39张图片

测试:
Spring(二)_第40张图片

2.3 切入点表达式的各种用法

在接口中定义一个新方法:
Spring(二)_第41张图片
实现方法:
Spring(二)_第42张图片
切面不变

测试:【调用show方法,切面没有切入,因为切面中的切入点指的非常详细】
Spring(二)_第43张图片
当把切面中的@Before改了后就可以切入了
第一种修改方法:
Spring(二)_第44张图片
第二种修改方法:【推荐使用】
在这里插入图片描述
第三种修改方法:

在这里插入图片描述
第四种修改方法:【不推荐使用】

在这里插入图片描述

2.4 AspectJ框架切换JDK动态代理和CGLib动态代理

将SomeService换为SomeServiceImpl后:
Spring(二)_第45张图片

重新绑定就可以进行切面切入
Spring(二)_第46张图片
总结:
在这里插入图片描述

2.5 前置通知注解方式实现

把声明对象的方式改为注解的方式

第一步:
Spring(二)_第47张图片
第二步:
Spring(二)_第48张图片
第三步:
Spring(二)_第49张图片
测试:
Spring(二)_第50张图片

2.6 前置通知方法参数JoinPoint解析

JoinPoint是一个接口,获取目标方法的各种信息
将切面修改:
Spring(二)_第51张图片
效果:
Spring(二)_第52张图片

2.7 @AfterReturning后置通知-注解有returning属性

流程分析
Spring(二)_第53张图片
代码实现【不修改返回值】:

  • 定义接口
    Spring(二)_第54张图片
  • 接口实现类
    在这里插入图片描述
  • 切面类
    Spring(二)_第55张图片
    添加扫描包和进行绑定:

在这里插入图片描述

测试:
Spring(二)_第56张图片
结果:
Spring(二)_第57张图片
代码实现【修改返回值】:
①对String类型的数据修改

Spring(二)_第58张图片

Spring(二)_第59张图片
总结:String类型不可修改

②对引用数据进行修改
定义student实体类:
Spring(二)_第60张图片
在接口中添加方法:
Spring(二)_第61张图片
实现方法:
Spring(二)_第62张图片
修改切面方法:
Spring(二)_第63张图片
测试:
Spring(二)_第64张图片

2.8 环绕通知@Around

它是通过拦截目标方法的方式,在目标方法前后增强功能的通知.它是功能最强大的通知,一般事务使用此通知.它可以轻易的改变目标方法的返回值

流程分析
Spring(二)_第65张图片
代码实现:
定义接口:
Spring(二)_第66张图片
接口实现类:
Spring(二)_第67张图片

切面类:
Spring(二)_第68张图片

配置文件:
Spring(二)_第69张图片
测试:
Spring(二)_第70张图片
结果:
Spring(二)_第71张图片

2.9 最终通知@After

无论目标方法是否正常执行,最终通知的代码都会被执行.

接口+接口实现:
在这里插入图片描述
Spring(二)_第72张图片
切面方法:
Spring(二)_第73张图片
配置文件:
Spring(二)_第74张图片
测试:
Spring(二)_第75张图片
Spring(二)_第76张图片
修改目标方法:
Spring(二)_第77张图片
再次测试:
Spring(二)_第78张图片

2.10 定义切入点别名 @Pointcut

先在切面类中添加各种通知【添加多个切面】:
Spring(二)_第79张图片
测试结果:
Spring(二)_第80张图片

问题:好多切入点表达式都重复了,需要重新进行取别名

如果多个切面切入到同一个切入点,可以使用别名简化开发.使用@Pointcut注解,创建一个空方法,此方法的名称就是别名.

Spring(二)_第81张图片

你可能感兴趣的