【Spring】难理解的Aop编程 | 入门?
作者:狮子也疯狂
专栏:《spring开发》
坚持做好每一步,幸运之神自然会驾凌在你的身上
目录
- 一. 🦁 前言
- 二. 🦁 常见概念
- 2.1 常见术语
- 2.2 AOP入门
- Ⅰ. 🐇 功能场景
- Ⅱ. 🐇 实现过程
- 2.3 通知类型
- Ⅰ. 🐇 编写通知方法
- Ⅱ. 🐇 编写切面
- Ⅲ. 🐇 测试
- 三. 🦁 切点表达式
- 3.1 使用语法
- 四. 🦁 总结
一. 🦁 前言
继上两篇文章,狮子总结了Spring中IOC的底层原理、基本使用以及注解使用。今天来细说一下Spring的另外一个重要原理——面向切面编程(Aspect Oriented Programming),即我们常说的AOP。它是实现功能统一维护的一种技术,它将业务逻辑的各个部分进行隔离,使开发人员在编写业务逻辑时可以专心于核心业务,从而提高了开发效率。
二. 🦁 常见概念
AOP 能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可扩展性和可维护性。
SpringAOP是基于动态代理的,如果要代理的对象实现了某个接口,那么SpringAOP就会使用JDK动态代理去创建代理对象
;而对于没有实现接口的对象,就无法使用JDK动态代理,转而使用CGlib动态代理生成一个被代理对象的子类来作为代理。
2.1 常见术语
名称 | 说明 |
---|---|
连接点(Joinpoint) | 指能被拦截到的点,在Spring中只有方法能被拦截 |
切点(Pointcut) | 指要对哪些连接点进行拦截,即被增强的方法。 |
通知(Advice) | 指拦截后要做的事情,即切点被拦截后执行的方法 |
切面(Aspect) | 切点+通知称为切面 |
目标(Target) | 被代理的对象 |
代理(Proxy) | 代理对象 |
织入(Weaving) | 生成代理对象的过程 |
2.2 AOP入门
现在来简单了解一下AOP的使用,SpringAOP中已经集成了AspectJ框架(应该是Java生态中最为完整的AOP框架了),我们使用该框架来实现一个简易的AOP功能。
Ⅰ. 🐇 功能场景
持久层的每个方法结束后都可以打印一条日志
Ⅱ. 🐇 实现过程
- 创建maven项目,并且引入以下依赖:
<!-- spring -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.12</version>
</dependency>
<!-- AspectJ -->
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.7</version>
</dependency>
<!-- junit -->
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope>
</dependency>
- 编写连接点(该处省略持久层接口)
@Repository
public class UserDaoImpl implements UserDao{public void add(){System.out.println("用户新增");||}public void delete(){System.out.println("用户删除");}public void update(){System.out.println("用户修改");}
}
- 编写通知类
public class MyAspectJAdvice {// 后置通知public void myAfterReturning() {System.out.println("打印日志...");}
}
- 配置切面
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
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">
<context:component-scan basepackage="com.jackie">
</context:component-scan><!-- 通知对象 -->
<bean id="myAspectJAdvice"
class="com.jackie.advice.MyAspectAdvice"></bean>
<!-- 配置AOP -->
<aop:config><!-- 配置切面 -->
<aop:aspect ref="myAspectJAdvice">
<!-- 配置切点 -->
<aop:pointcut id="myPointcut"
expression="execution(*com.jackie.dao.UserDao.*(..))"/>
<!-- 配置通知 -->
<aop:after-returning method="myAfterReturning" pointcut-ref="myPointcut"/></aop:aspect></aop:config>
</beans>
- 测试
public class UserDaoTest {@Testpublic void testAdd(){ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");UserDao userDao = (UserDao)ac.getBean("userDao");userDao.add();}@Testpublic void testDelete(){ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");UserDao userDao = (UserDao)ac.getBean("userDao");userDao.delete();}@Testpublic void testUpdate(){ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");UserDao userDao = (UserDao)ac.getBean("userDao");userDao.update();}
}
通过调用就会发现,每个方法都会打印语句:打印日志...
。这就是AOP的使用入门。
2.3 通知类型
我们通过上面的案例会发现,这里写了一个后置通知,那么有哪些类型的通知呢?我们来看看:
通知类型 | 描述 |
---|---|
前置通知 | 在方法执行前添加功能 |
后置通知 | 在方法正常执行后添加功能 |
异常通知 | 在方法抛出异常后添加功能 |
最终通知 | 无论方法是否抛出异常,都会执行该通知 |
环绕通知 | 在方法执行前后添加功能 |
我们通过案例来看看这些通知类型的实现以及使用
Ⅰ. 🐇 编写通知方法
通过构造MyAspectAdvice通知类,在里面编写通知方法。
// 通知类
public class MyAspectAdvice {// 后置通知public void myAfterReturning(JoinPoint joinPoint) {System.out.println("切点方法名:" + joinPoint.getSignature().getName());System.out.println("目标对象:" + joinPoint.getTarget());System.out.println("打印日志" + joinPoint.getSignature().getName() + "方法被执行了!");}// 前置通知public void myBefore() {System.out.println("前置通知...");}// 异常通知public void myAfterThrowing(Exception ex) {System.out.println("异常通知...");System.err.println(ex.getMessage());}// 最终通知public void myAfter() {System.out.println("最终通知");}// 环绕通知public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("环绕前");Object obj = proceedingJoinPoint.proceed(); // 执行方法System.out.println("环绕后");return obj;}
}
Ⅱ. 🐇 编写切面
<!-- 配置AOP -->
<aop:config><!-- 配置切面 --><aop:aspect ref="myAspectJAdvice"><!-- 配置切点 --><aop:pointcut id="myPointcut" expression="execution(* com.jackie.dao.UserDao.*(..))"/><!-- 前置通知 --><aop:before method="myBefore" pointcut-ref="myPointcut"></aop:before><!-- 后置通知 --><aop:after-returning method="myAfterReturning" pointcut-ref="myPointcut"/><!-- 异常通知 --><aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointcut" throwing="ex"/><!-- 最终通知 --><aop:after method="myAfter" pointcut-ref="myPointcut"></aop:after><!-- 环绕通知 --><aop:around method="myAround" pointcut-ref="myPointcut"></aop:around></aop:aspect>
</aop:config>
Ⅲ. 🐇 测试
在这里就不阐述了,跟上面的案例是一样的。
三. 🦁 切点表达式
我们上面的几个案例中都用到了切点表达式,即:
使用AspectJ需要使用切点表达式配置切点的位置。
3.1 使用语法
访问修饰符 返回值 包名.类名.方法名(参数列表)
遵循以下习惯:
- 访问修饰符可以省略、返回值使用 * 代表任意类型、包名使用 * 表示任意包,多级包结构要写多个 * ,使用
*..
表示任意包结构- 类名和方法名都可以用 * 实现通配。
- 参数列表
基本数据类型直接写类型
引用类型写 包名.类名
*
表示匹配一个任意类型参数
..
表示匹配任意类型任意个数的参数- 全通配:
* *..*.*(..)
四. 🦁 总结
今天总结了AOP的基本使用方法。通过使用AspectJ框架来实现AOP的基本用法以及介绍了该框架的几种通知类型。今天的分享到这里,希望您喜欢!
相关文章:

【Spring】难理解的Aop编程 | 入门?
作者:狮子也疯狂 专栏:《spring开发》 坚持做好每一步,幸运之神自然会驾凌在你的身上 目录一. 🦁 前言二. 🦁 常见概念2.1 常见术语2.2 AOP入门Ⅰ. 🐇 功能场景Ⅱ. 🐇 实现过程2.3 通知类型Ⅰ.…...

2 月 25 日,论道京城 | 云原生开源项目应用实践报名开启
在数字化转型的浪潮中,云原生已经逐渐成为人们关注的焦点。开源社区作为云原生技术创新的根据地,为云原生的产业发展打造了丰富的技术生态圈,也在广泛的实践中源源不断地创造着新的机遇。想知道云原生存储技术实现了怎样的突破吗?…...
第五、六章 贪心算法、回溯算法
贪心算法 适合于贪心算法求解的问题具有:贪心选择性质、最优子结构性质。 贪心算法可以获取到问题的局部最优解,不一定能获取到全局最优解。 贪心算法总是作出在当前看来最好的选择;并且每次贪心选择都能将问题化简为一个更小的与原问题具有…...

k8s-kubectl命令
文章目录一、kubectl 基本命令1、陈述式资源管理方法:2、声明式资源管理办法二、基本信息查看三、项目的生命周期创建kubectl run命令四、金丝雀发布(Canary Release)——陈述式管理方法五、声明式管理方法kubectl create 和 kubectl apply区别一、kubectl 基本命令 1、陈述式…...

36、基于51单片机频率计 LCD 1602显示系统设计
摘要 数字频率计是一种基本的测量仪器。它被广泛应用于航天、电子、测控等领域,还被应用在计算机及各种数学仪表中。一般采用的是十进制数字,显示被测信号频率。基本功能是测量正弦信号,方波信号以及其他各种单位时间内变坏的物理量。由于其…...

【vue】elemente-ui table toggleRowSelection 默认选择无效[已解决]
项目场景: 点击按钮,弹出一个弹出框,内部出现一个table表,表内数据是动态获取,同时得勾选上几个table表的数据,类似以下的图 问题描述 点击按钮显示弹出框,加载table中的数据,默…...
SpringMVC DispatcherServlet源码(5) HttpMessageConverter扩展
前文通过阅读源码,深入分析了DispatcherServlet及相关组件的工作流程,本文不再阅读源码,介绍一下扩展HttpMessageConverter的方式。 HttpMessageConverter工作方式及扩展方式 前文介绍过,HttpMessageConverter是读写请求体和响应…...
day16_API
今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、作业 二、String 三、StringBuffer&StringBuilder 四、日期 零、 复习昨日 见晨考 一、String String代表字符串,类,java程序中的所有字符串&…...

十二月券商金工精选
✦研报目录✦ ✦简述✦ 按发布时间排序 华宝证券 主动暴露的得与失—从Barra框架到私募指增因子分析方法 发布日期:2022-12-01 关键词:股票、Barra、风险暴露、指数增强 主要内容:本文针对私募指数增强产品的策略流程,设计…...
JUnit
Junit 简介 JUnit是一个开源的java单元测试框架,它是XUnit测试体系架架构的一种体现 是Java语言事实上的标准单元测试库真正的优势来自于JUnit所采作用的思想和技术,而不是框架本身。推动了单元测试、测试先行的编程和测试驱动的开发JUnit衍生了许多xUn…...
MySQL学习笔记4-乐观锁和悲观锁
1.定义 乐观锁和倍灌水是并发控制采用的技术手段,确保当多个数位同时对数据中同一数据存取时,不会破坏事物的隔离性、统一性和数据库统一性 乐观锁 假定不会发生并发冲突,只在提交操作时检测是否违反数据完整性 实现方式: 记录…...
踩大坑:json格式存储wav二进制内容
需求描述: 需要将wav音频文件以二进制的形式读出,存放到 json 中,发送post请求到服务,服务解析json,得到二进制内容后放进ASR模型得出转录结果。 记一次坑: # 将wav以二进制形式读出存放到json中 f ope…...

加入CSDN的一年,我收获了这些……
加入CSDN的一年,我收获了这些……加入CSDN的一年,我收获了这些……加入CSDN的一年,我收获了这些…… 🚀🚀时光如白驹过隙般,飞逝而过。一转眼,我就已经是一名大二的学生了,也已经在…...

【Python学习笔记】44.Python3 MongoDB和urllib
前言 本章介绍Python的MongoDB和urllib。 Python MongoDB MongoDB 是目前最流行的 NoSQL 数据库之一,使用的数据类型 BSON(类似 JSON)。 PyMongo Python 要连接 MongoDB 需要 MongoDB 驱动,这里我们使用 PyMongo 驱动来连接。…...

LVS中的keepalived高可用
文章目录前言一、Keepalived简介二、keepalived工作原理三、配置文件四、实验1.某台Real Server down2.LVS本身down实验过程:五、代码详细演示整体过程调度器安装软件、设置测试keepalived对后端RS的健康检测backup服务主机设置前言 一、Keepalived简介 Keepalived是…...

【Vue3】组件数据懒加载
组件数据懒加载-基本使用 目标:通过useIntersectionObserver优化新鲜好物和人气推荐模块 电商类网站,尤其是首页,内容有好几屏,而如果一上来就加载所有屏的数据,并渲染所有屏的内容会导致首页加载很慢。 数据懒加载&a…...

基于 SmartX 分布式存储的 iSCSI 与两种 NVMe-oF 技术与性能对比
作者:深耕行业的 SmartX 金融团队本文重点SmartX 分布式块存储 ZBS 提供 2 种存算分离架构下的数据接入协议,分别是 iSCSI 和 NVMe-oF。其中,iSCSI 虽然具有很多优势,但不适合支持高性能的工作负载,这也是 SmartX 选择…...
Anaconda 安装 Pytorch
下载Anaconda,最新版本的即可,默认安装,最好不要安装在C盘,否则后面C盘容量会很大。 安装Pytorch 打开 Anaconda Prompt ,先切换镜像源为国内清华镜像源,这样安装包的时候下载速度会快一些,也容易成功一些。 在 Anaconda Prompt 命令行依次输入以下四条命令切换到清华镜…...

从零开始使用MMSegmentation训练Segformer
从零开始使用MMSegmentation训练Segformer 写在前面:最新想要用最新的分割算法如:Segformer or SegNeXt 在自己的数据集上进行训练,但是有不是搞语义分割出身的,而且也没有系统的学过MMCV以及MMSegmentation。所以就折腾了很久&am…...

会利用信息差赚钱的人才是聪明人
毕业后找不到工作,穷到只剩下时间,大小做了20多份副业兼职,终于找到了可靠的渠道, 我是专科生,学历不好,专业拉胯。毕业后,我找了两三份工作。要么工资太低,只能交房租,…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...