Spring AOP续--织入

news/2024/12/4 4:27:57/

上篇讲到SpringAOP的一些用法以及概念,这里我们单独讲一下AOP中的“织入”。
我们知道,SpringAOP是基于动态代理实现的技术,而织入则是一个生成动态代理对象并且将切面和目标对象方法编织成为约定流程的过程。

对于通知,上篇文章中都是采用接口+实现类的方式,这也是Spring推荐的方式,但并不是强制的,动态代理的实现方式也是有很多种的,目前主流的就是JDK、CGLIB、Javassist、ASM等。对于Spring来说,它采用了JDK、CGLIB动态代理方式。

首先我们来看看JDK、CGLIB动态代理的区别。

JDK、CGLIB动态代理的区别

JDK动态代理

JDK代理使用的是反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
JDK创建代理对象效率较高,执行效率较低;
JDK动态代理机制是委托机制,只能对实现接口的类生成代理,通过反射动态实现接口类;
JDK代理是不需要依赖第三方的库,只要JDK环境就可以进行代理,需要满足以下要求:
 1.实现InvocationHandler接口,重写invoke()
 2.使用Proxy.newProxyInstance()产生代理对象
 3.被代理的对象必须要实现接口

CGLIB动态代理

CGLIB代理使用字节码处理框架asm,对代理对象类的class文件加载进来,通过修改字节码生成子类。
CGLIB创建代理对象效率较低,执行效率高。
CGLIB则使用的继承机制,针对类实现代理,被代理类和代理类是继承关系,所以代理类是可以赋值给被代理类的,因为是继承机制,不能代理final修饰的类。
CGLib 必须依赖于CGLib的类库,需要满足以下要求:
 1.实现MethodInterceptor接口,重写intercept()
 2.使用Enhancer对象.create()产生代理对象

参考:https://blog.csdn.net/qq_59527118/article/details/127386305

Spring Boot动态代理验证

Spring Boot会自己判断使用哪种代理,如果被代理类有接口,就采用JDK动态代理,否则就采用CGLIB动态代理。
然而,在Spring Boot2.X版本中,Spring Boot不管被代理类是否有实现接口,都会默认采用CGLIB动态代理,如果要让其使用JDK动态代理,则需要在application.properties文件中添加以下配置:

spring.aop.proxy-target-class=false

下面让我们一起验证以下。
首先我们创建两个service类,一个实现了接口,一个没有实现接口,代码如下:

@Service
@Slf4j
public class UserServiceImpl implements IUserService{@Overridepublic void printUser(User user) {if(null == user){throw new IllegalArgumentException();}log.info("用户信息如下:{}", user.toString());}
}@Service
@Slf4j
public class UserServiceNoImpl{public void printUser(User user) {if(null == user){throw new IllegalArgumentException();}log.info("用户信息如下:{}", user.toString());}
}

然后将这两个类的printUser都创建切点以及通知,再创建测试controller:

@RestController
@Slf4j
public class UserController {@Autowiredprivate IUserService userService;@Autowiredprivate UserServiceNoImpl userServiceNo;@GetMapping("/getUser")public User getUser(){User user = new User().setId(111).setName("admin").setNote("aop测试");// 实现了接口userService.printUser(user); // 断点处// 没有实现接口userServiceNo.printUser(user);try {userService.printUser(null);}catch (Exception e){log.warn("获取用户信息异常:");}return user;}

此时application.properties文件中不添加“spring.aop.proxy-target-class=false”,最后启动应用,访问地址,结果如下:
在这里插入图片描述
可以看到,此时UserServiceImpl 类有实现接口,但是Spring Boot仍然使用了CGLIB代理。

下面让我们在application.properties文件中添加“spring.aop.proxy-target-class=false”,再次启动应用,访问地址,结果如下:
在这里插入图片描述
可以看到,UserServiceImpl 类有实现接口,Spring Boot使用了JDK代理。

好了,今天就先到这里了,眼过千遍不如手过一遍,赶紧去自己尝试一下吧。。。。拜拜


http://www.ppmy.cn/news/61009.html

相关文章

【五一创作】网络协议与攻击模拟-01-wireshark使用-捕获过滤器

协议 TCP/IP协议簇 网络接口层(没有特定的协议)PPPOE 物理层 数据链路层 网络层:IP (v4/v6) ARP (地址解析协议) RARP ICMP (Internet控制报文协议) IGMP 传输层:TCP(传输控制协议) UDP(用户数据报协议) 应用层:都是基于传输层协议的端口,总共端口0~65535 0~1023 HTTP—t…

【大数据处理与可视化】四、数据预处理

【大数据处理与可视化】四、数据预处理 实验目的实验内容实验步骤一、案例——预处理部分地区信息1、导包2、读取文件3、检查并删除重复数据北京天津(无重复数据) 4、检查缺失值北京(无缺失值)天津(向前填充&#xff0…

Midjourney关键词分享!附输出AI绘画参考图

Midjourney 关键词是指用于 Midjourney 这个 AI 绘画工具的文本提示,可以影响生成图像的风格、内容、细节等。Midjourney 关键词有一些基本的语法规则和套用公式,也有一些常用的风格词汇和描述词汇,这里我以10张不同风格和类型的美女图为例&a…

【提示学习】Label prompt for multi-label text classification

论文信息 名称内容论文标题Label prompt for multi-label text classification论文地址https://link.springer.com/article/10.1007/s10489-022-03896-4研究领域NLP, 文本分类, 提示学习, 多标签提出模型LP-MTC(Label Prompt Multi-label Text Classification model)来源Appli…

【大数据之Hadoop】从自定义 RPC 到 Hadoop RPC ,理解分布式通信系统的底层工作原理

1. 前言 Hadoop是分布式计算系统,在分布式环境中,网络通信模块是其核心模块之一。要学好Hadoop,需理解其底层通信系统的基本工作原理。Hadoop提供有体系完整的RPC框架,实现了对底层网络通信过程的优雅封装。 本文将从RPC概念说起…

【python】列表、字典、元组与集合的特点以及对比

一、列表(List) 1. 列表的特点 数据按顺序存储列表有正序、倒序两种索引列表可存储任意类型的数据,并且允许重复。 2. 列表的遍历: lst[1,2,3] for i in range(len(lst)):print(lst[i],end" ")3. 列表的缺点&#x…

《针灸》笔记(倪海厦先生人纪系列针灸篇)

程序员上了年纪,各种职业病就来了,人工智能成为好工具的同时,自己的时间也多了一些。 了解他才能判断他的真伪,没学过就认为中医是糟粕的,请划走。 学到什么记什么,线上线下齐下手,自用笔记&…

听我一句劝,别去外包,干了6年,废了....

先说一下自己的情况,大专生,18年通过校招进入湖南某软件公司,干了接近6年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了6年的功能测试&…