AOP介绍
aop:Aspect Oriented Programming,面向切面编程。是通过预编译方式(aspectj)或者**运行期动态代理**(Spring)实现程序功能的统一维护的技术。
AOP是OOP(面向对象编程)的技术延续,是软件开发中的一个热点,也是Spring中的一个重要内容。利用AOP可以实现对业务逻辑各个部分之间的隔离,从而使得业务逻辑各部分之间的耦合性降低,提高程序的可重用性,同时提高了开发效率。
- aop的作用:在不修改源码的情况下,进行功能增强,通过动态代理实现的
*```
优势:减少重复代码,提高开发效率,方便维护
* aop的底层实现:底层是通过动态代理实现的。在运行期间,通过代理技术动态生成代理对象,代理对象方法执行时进行功能的增强介入,再去调用目标的方法从而完成功能的增强
1.常见的动态代理技术有:
1. jdk的动态代理:基于接口实现的
2. cglib的动态代理:基于子类实现的 Spring的aop采用了哪种代理方式
3. 如果目标对象有接口,就采用JDK动态代理技术
4. 如果目标对象没有接口就采用cglib技术
### AOP相关概念 ###
连接点:能够被增强的方法都是连接点
切入点:已经增强的连接点叫切入点
通知/增强:对目标对象增强的代码
切面:是切入点和切面的结合
### AOP开发前要明确的事项 ###
我们需要做的事情
编写核心业务(目标类的相关方法)
编写通知类,通知类有通知方法(Advice增强功能方法)
在配置文件中配置织入关系,完成完整的代码逻辑运行
Spring的AOP做的事情
生成动态代理的过程(把通知织入到切入点的过程),是由spring来实现的
Spring会监控切入点方法的执行,一旦发现切入点方法执行,使用代理机制动态创建目标对象的代理对象,根据通知的类别,在代理对象的对应位置,将通知对应的功能织入完成完整代码的逻辑运行
### 基于xml的AOP ###
入门实现:
##### 1.导入aop的依赖 #####
![202301012100184741.png][]
##### 2.创建目标类和通知类 #####
public interface UserService {
void add();
void update();
}
public class UserServiceImpl implements UserService {
public void add() {
System.out.println("调用了UserServiceImpl的add方法~!");
//int a = 1 / 0 ;
}
public void update() {
System.out.println("调用了UserServiceImpl的update方法~!");
}
通知类(增强类):
public class MyAdvice {
public void print(){
System.out.println("打印日志~!");
}
##### 3.写配置文件 #####
![202301012100199702.png][]
![202301012100207283.png][]
#### 通知类型的介绍 ####
前置通知 <aop:before> 通知方法在切入点方法之前执行
后置通知 <aop:after-rurining> 在切入点方法执行后,执行通知方法
异常通知 <aop:after-throwing> 在切入点方法抛出异常时,执行通知方法
最终通知 <aop:after> 无论切入点是否有异常,最终都会执行该方法
环绕通知 <aop:around> 通知方法在切入点之前还有之后都会执行
切面表达式的抽取,如果我们对一个方法在不同位置进行增强时,切面表达式重复多余,所以我们可以进行抽取
![202301012100219094.png][]
### 基于注解的AOP ###
第一步:开启AOP自动代理和IOC扫描包
<context:component-scan base-package="com.albb"/>
<aop:aspectj-autoproxy/>
第二步:在增强类和目标类头上打上注解让spring为其创建对象
第三步:在增强类头上打上@Aspect注解,告诉spring我是增强类,是用来做增强的
第四步:在通知方法上打上@After(切面表达式)...注解告诉spring要增强在目标方法的哪个位置,要增强哪个方法
@Component
@Aspect
public class MyAdvice {
@Before("execution(* com.itheima..*.*(..))")
public void print(){
System.out.println("打印日志~");
}
### 纯注解的方式 ###
纯注解是依赖于核心配置类的,我们创建一个核心配置类
在他头上打上
@configuration 表示这是一个核心配置类
@ComponentScan("com.albb“)表示开启ioc扫描包
@EnableAspectJAutoProxy 表示开启aop自动代理
### 基于XML的声明事务控制 ###
1.定义事务的管理员
![202301012100224065.png][]
2.定义事务规则
![202301012100231906.png][] 3.定义切面
![202301012100238927.png][]
### 注解的方式声明事务控制 ###
1.定义事务管理员
2.开启事务注解
<tx:annotation-driven transaction-manager="tm"/>
3.在要开启事务的类或者方法上添加@Transactional
### 纯注解的方式声明事务控制 ###
1.定义配置类
添加@EnableTransactionManager,表示开启事务注解
2.使用@Bean在配置类中创建事务管理员
3.给要使用事务的类或者方法添加@Transactional注解
[202301012100184741.png]: http://image.skjava.com/article/common/2023/1/202301012100184741.png
[202301012100199702.png]: http://image.skjava.com/article/common/2023/1/202301012100199702.png
[202301012100207283.png]: http://image.skjava.com/article/common/2023/1/202301012100207283.png
[202301012100219094.png]: http://image.skjava.com/article/common/2023/1/202301012100219094.png
[202301012100224065.png]: http://image.skjava.com/article/common/2023/1/202301012100224065.png
[202301012100231906.png]: http://image.skjava.com/article/common/2023/1/202301012100231906.png
[202301012100238927.png]: http://image.skjava.com/article/common/2023/1/202301012100238927.png