一、AOP概述
1. 什么是AOP?
AOP: Aspect Oriented Programming,面向切面编程
它将重复的代码抽取出来,使用动态代理技术,在不修改源码的基础上对已有的方法进行增强
动态代理是在程序运行期间执行,静态代理是在程序编译期间执行。
优势:
- 减少重复代码
- 提高开发效率
- 维护方便
2. AOP具体应用
我们使用了connection对象的setAutoCommit(true),这样会导致一些问题,比如在向数据库插入数据的时候,出现异常不会回滚,依然会成功插入。
此时可以通过业务层控制事务的提交和回滚
之前是通过connectionUtils类获取当前线程绑定的连接,返回线程连接。
再通过MyTransactionManager类,处理事务提交、回滚等。
但是这样会导致业务层方法和事务控制方法耦合
于是我们使用AOP,通过配置的方式实现动态代理。
相关术语
joinpoint连接点:能被拦截到的点,即方法
pointcut切入点:指对哪些joinpoint进行拦截
aspect切面:通知和切入点的结合
weaving织入:把切面应用到目标对象来创建新的代理对象
introduction引入:不修改类代码的前提下,动态地添加一些方法或field
学习AOP要明确的事:
a.开发阶段
编写核心业务代码 -> 抽取公用代码,制作成通知 -> 配置文件中声明切入点与通知间的关系
b.运行阶段
spring框架监控切入点方法的执行,一旦监控到,则使用代理机制,动态创建目标对象的代理对象,根据通知类别在代理对象对应位置织入相应的功能
3. 基于XML的AOP配置
1. 在pom.xml中引入相关依赖
<!--aop切面相关的包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.18</version>
</dependency>
<!--事务包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.3.18</version>
</dependency>
2. 创建spring配置文件并导入约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
3. 配置文件applicationContext.xml
4. 抽取公共代码制作成通知
1. 把通知类用bean标签配置起来
用@Component注解创建了MyTransactionManager对象
2. aop:config声明aop配置
使用<aop:config></aop:config>
标签声明开始aop的配置
3. 使用aop:aspect配置切面
使用aop:aspect配置切面
id:切面的唯一标识
ref:引用通知类bean的id
<aop:aspect ref="myTransactionManager" id="txAdvice"></aop:aspect>
4. 使用aop:pointcut配置切入点表达式
aop:pointcut: 用于配置切入点表达式
id:切入点表达式的唯一标识
expression:定义切入点表达式
<aop:pointcut id="pointcut1" expression="execution(* com.woniu.service.impl.*.*(..))" />
5. 使用aop:xxx配置对应的通知类型
method:指定通知中方法的名称
pointcut-ref:切入点表达式的引用
前置通知:<aop:before method="" pointcut-ref="" />
后置通知:<aop:after-returning method="" pointcut-ref="" />
异常通知:<aop:after-throwing method="" pointcut-ref="" />
最终通知:<aop:after method="" pointcut-ref="" />
环绕通知:<aop:around method="" pointcut-ref="" />