Spring系统学习(四)——Spring AOP

news2024/9/25 21:19:45

1. Spring AOP 介绍

AOP (Aspect-Oriented Programming,面向切面编程) 是一种编程范式,它允许将跨领域的关注点(如日志记录、事务管理、权限控制等)与业务逻辑分离,达到代码的分离与解耦。Spring AOP 是 Spring 框架中的一个模块,帮助开发者轻松实现 AOP 功能。

Spring AOP 概述

Spring AOP 是基于代理的,它可以在方法的执行之前、之后或者抛出异常时,插入额外的行为,而不改变原有的业务代码。Spring AOP 常用于处理系统的横切关注点(Cross-cutting concerns),如:

  • 日志记录
  • 权限控制
  • 性能监控
  • 事务管理
Spring AOP 术语

理解以下 AOP 相关术语有助于掌握 AOP 概念:

  • 切面 (Aspect):一个模块,封装了跨领域逻辑(如日志或事务)。切面可以横切多个业务模块。
  • 连接点 (Join Point):程序执行的某个位置,比如方法调用、异常抛出等。Spring AOP 主要关注方法执行的连接点。
  • 通知 (Advice):在切面中定义的动作,指定在何时执行特定行为。通知的类型包括:
    • 前置通知 (Before Advice):在方法调用前执行。
    • 后置通知 (After Advice):在方法执行完毕后执行(无论是否抛出异常)。
    • 返回通知 (After Returning Advice):在方法正常返回后执行。
    • 异常通知 (After Throwing Advice):在方法抛出异常时执行。
    • 环绕通知 (Around Advice):包裹方法的执行,在方法调用前后都可以执行自定义逻辑。
  • 切入点 (Pointcut):定义了连接点的集合,用来指定哪些方法应该应用通知。
  • 引入 (Introduction):允许在不修改代码的情况下,为类添加新方法或属性。
  • 目标对象 (Target Object):被通知的对象,也就是被代理的对象。
  • 代理 (Proxy):由 AOP 框架创建的对象,用于实现切面功能。
  • 织入 (Weaving):将切面应用到目标对象并创建代理对象的过程。在 Spring 中,这个过程是在运行时完成的。

2. Spring AOP 的实现机制

Spring AOP 的实现主要基于 JDK 动态代理CGLIB 动态代理,具体使用哪种代理机制取决于目标类是否实现了接口。

1. JDK 动态代理
  • 原理:JDK 提供的动态代理机制要求目标对象必须实现一个或多个接口。Spring AOP 通过 java.lang.reflect.Proxy 类动态生成代理对象,在方法调用时,代理对象会将调用转发给实际的目标对象,同时执行通知逻辑。
  • 适用场景:适用于目标类实现了接口的情况。
  • 特点:基于接口代理,性能较好,但无法代理没有实现接口的类。
2. CGLIB 动态代理
  • 原理:CGLIB 是一个开源项目,它通过生成目标类的子类来创建代理对象。Spring AOP 会使用 CGLIB 代理那些没有实现接口的类。CGLIB 使用字节码操作技术生成代理类。
  • 适用场景:适用于目标类没有实现接口的情况。
  • 特点:基于类的代理,代理的是类本身(生成目标类的子类),但无法代理 final 方法和类,性能相对较低。

在实际使用中,Spring 默认优先使用 JDK 动态代理,如果类没有实现任何接口,Spring 会使用 CGLIB 代理。

3. 基于 XML 的 AOP 实现

Spring 支持通过 XML 配置文件来实现 AOP,这种方式较为传统,但对于理解 AOP 的工作原理非常直观。实现步骤如下:

1. 引入 AOP 命名空间
<beans xmlns="http://www.springframework.org/schema/beans"
       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/aop 
                           http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
2. 配置切面和切入点
<!-- 定义切面类 -->
<bean id="myAspect" class="com.example.MyAspect"/>

<!-- 配置 AOP 切入点与通知 -->
<aop:config>
    <!-- 定义切入点,匹配业务层的所有方法 -->
    <aop:pointcut id="myPointcut" expression="execution(* com.example.service.*.*(..))"/>

    <!-- 配置通知 -->
    <aop:advisor advice-ref="myAspect" pointcut-ref="myPointcut"/>
</aop:config>
3. 切面类的定义
public class MyAspect {
    public void beforeAdvice() {
        System.out.println("前置通知:方法调用前执行");
    }
}

4. 基于注解的 AOP 实现

Spring 从 2.0 开始支持基于注解的 AOP 配置,这种方式更简洁和易于维护。

1. 启用 AOP 支持

在 Spring 配置文件中启用注解驱动的 AOP:

<aop:aspectj-autoproxy />

或者在配置类上使用 @EnableAspectJAutoProxy 注解:

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
    // 配置类
}
2. 定义切面类并使用注解
@Aspect
@Component
public class MyAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void beforeAdvice() {
        System.out.println("前置通知:方法调用前执行");
    }
    
    @AfterReturning("execution(* com.example.service.*.*(..))")
    public void afterReturningAdvice() {
        System.out.println("返回通知:方法调用成功后执行");
    }

    @Around("execution(* com.example.service.*.*(..))")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕通知:方法调用前");
        Object result = joinPoint.proceed();  // 调用目标方法
        System.out.println("环绕通知:方法调用后");
        return result;
    }
}

5. 小结

Spring AOP 作为面向切面编程的一部分,提供了一种优雅的方式来处理横切关注点。Spring AOP 主要通过 JDK 动态代理CGLIB 动态代理 实现,支持 XML 配置注解方式 两种配置方式。掌握 Spring AOP 的概念、术语和实现方式,可以帮助你轻松实现事务管理、日志记录等功能而不侵入业务逻辑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2164819.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java核心基础

文章目录 1. Java开发基础1.1 DOS常用命令:&#xff08;以MAC常用命令比较&#xff09;1.2 JVM、JRE、JDK之间的关系1.3 Java开发环境的搭建1.4 Java的注释&#xff0c;标识符、标识符的命名规范1.5 变量和常量的定义及初始化1.6 Java的运算符1.7 三大语句1.8 常用的类1.8.1 ja…

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-21

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-21 1. AIvril: AI-Driven RTL Generation With Verification In-The-Loop Authors: Mubashir ul Islam, Humza Sami, Pierre-Emmanuel Gaillardon, and Valerio Tenace AIVRIL: 人工智能驱动的RTL生成与验证内…

OpenAPI鉴权(二)jwt鉴权

一、思路 前端调用后端可以使用jwt鉴权&#xff1b;调用三方接口也可以使用jwt鉴权。对接多个三方则与每个third parth都约定一套token规则&#xff0c;因为如果使用同一套token&#xff0c;token串用可能造成权限越界问题&#xff0c;且payload交叉业务不够清晰。下面的demo包…

springBoot --> 学习笔记

文章目录 认识 SpringBoot第一个 SpringBoot 程序彩蛋 banner &#xff08;emmmmm&#xff0c;哈哈哈哈哈哈&#xff0c;牛逼&#xff01;&#xff09;SpringBoot 配置配置文件第一个 yaml 配置 成功案例yaml 存在 松散绑定 JSR 303 数据校验多环境配置以及文件位置访问静态资源…

教你制作一个二维码就能查分的系统

学生和家长对于成绩查询的需求日益增长。为了满足这一需求&#xff0c;很多学校和老师开始使用二维码查询系统&#xff0c;以提高效率和保护隐私。以下内容就是如何制作一个简单易用的成绩查询二维码系统的步骤&#xff1a; 1. 准备电子表格 老师需要准备一个包含学生成绩的电…

(已解决)vscode如何传入argparse参数来调试/运行python程序

文章目录 前言调试传入参数运行传入参数延申 前言 以前&#xff0c;我都是用Pycharm专业版的&#xff0c;由于其好像在外网的时候&#xff0c;不能够通过VPN来连接内网服务器&#xff0c;我就改用了vscode。改用了之后&#xff0c;遇到一个问题&#xff0c;调试或者运行python…

基于Qt5.12.2开发 MQTT客户端调试助手

项目介绍 该项目是一个基于 Qt 框架开发的桌面应用程序&#xff0c;主要用于与 MQTT 服务器进行连接和通信。通过该应用&#xff0c;用户可以连接到 MQTT 服务器&#xff0c;订阅主题、发布消息并处理接收到的消息。项目使用 QMqttClient 类来实现 MQTT 协议的客户端功能&…

第128集《大佛顶首楞严经》

《大佛顶如来密因修正了义诸菩萨万行首楞严经》。监院法师慈悲&#xff0c;诸位法师&#xff0c;诸位同学&#xff0c;阿弥陀佛&#xff01; 请大家打开讲义296面。 庚一、总示阴相&#xff08;分四&#xff1a;辛一、结前行阴尽相。辛二、正明识阴区宇。辛三、悬示识阴尽相。…

通过frp 免费内网穿透,端口转发

1.准备工作 (1)拥有一台有公网IP的服务器(系统可以是windows/macos/linux),服务器可以使用云厂商购买的服务器 (2)从下面链接下载最新版本的frp安装包,客户端和服务端是同一个tar包 https://github.com/fatedier/frp/releases 服务端机器A-有外网ip的作为服务端 服务端机器B-需…

前端接口415状态码【解决】

前端接口415状态码【解决】 一、概述 415状态码是HTTP协议中的一个标准响应状态码&#xff0c;代表“Unsupported Media Type”&#xff08;不支持的媒体类型&#xff09;。当客户端尝试上传或发送一个服务器无法处理的媒体类型时&#xff0c;服务器会返回这个状态码。这通常意…

二维四边形网格生成算法:paving(五)缝合 Seaming 与 闭合检测 Closure Check

欢迎关注更多精彩 关注我&#xff0c;学习常用算法与数据结构&#xff0c;一题多解&#xff0c;降维打击。 参考论文&#xff1a;Paving: A new approach to automated quadrilateral mesh generation 关注公众号回复paving可以获得文章链接 paving&#xff08;一&#xff0…

python如何将字符转换为数字

python中的字符数字之间的转换函数 int(x [,base ]) 将x转换为一个整数 long(x [,base ]) 将x转换为一个长整数 float(x ) 将x转换到一个浮点数 complex(real [,imag ]) 创建一个复数 str(x ) 将对象 x 转换为字…

Pytest测试实战|执行常用命令

Pytest测试实战 本文章主要详细地阐述下Pytest测试框架执行TestCase常用命令。 按分类执行 在Pytest测试框架中按照分类执行的命令为“-k”&#xff0c;它的主要特点是按照TestCase名字的模式来执行&#xff0c;在编写具体的TestCase的时候&#xff0c;都会编写每个TestCase…

el-table表格点击该行任意位置时也勾选上其前面的复选框

需求&#xff1a;当双击表格某一行任意位置时&#xff0c;自动勾选上其前面的复选框 1、在el-table 组件的每一行添加row-dblclick事件&#xff0c;用于双击点击 <el-table:data"tableData"ref"tableRef"selection-change"handleSelectionChange&q…

常用组件详解(五):torch.nn.BatchNorm2d()

文章目录 一、基本原理二、函数说明 在卷积神经网络的卷积层之后通常会添加torch.nn.BatchNorm2d()进行数据的归一化处理&#xff0c;将数据规范到均值为0&#xff0c;方差为一的分布上&#xff0c;使得数据在进行Relu时不会因为数据过大而导致网络性能的不稳定。 一、基本原理…

基础实践:使用JQuery Ajax调用Servlet

前言 本博客介绍最简单的JQuery&#xff08;原生JS的封装库&#xff09;使用Ajax发送请求&#xff0c;并通过对应的servlet响应数据&#xff0c;并在页面显示&#xff0c;并且servlet响应的数据来自MySQL数据库。 实现需求&#xff1a;在前端页面的输入框中输入要注册的用户名&…

2024年_ChatGPT 及类似的人工智能技术带来的影响与改变 怎样利用 ChatGPT 提高学习效率

人工智能技术给我们带来了什么的改变&#xff1a; 工作方式与效率&#xff1a; 信息检索与处理&#xff1a;能快速整合大量信息&#xff0c;提供较为准确的答案和建议&#xff0c;帮助人们更高效地获取所需知识&#xff0c;提升信息检索和处理的速度与质量&#xff0c;比如在做…

Git版本控制的使用教程

使用Git进行项目代码的版本控制&#xff0c;具体操作&#xff1a; 1). 创建Git本地仓库 当Idea中出现&#xff1a; 说明本地仓库创建成功。 2). 创建Git远程仓库 访问Gitee - 基于 Git 的代码托管和研发协作平台&#xff0c;新建仓库 点击 创建 3). 将本地文件推送到Git远程…

Java【根据数据库生成实体文件】

下载插件 安装 MybatisX 配置包 Scratches and Consoles -> Extensions&#xff0c;Reload from Disk 后&#xff0c;会出现 MyBatisX 文件夹&#xff0c;将模板配置文件夹&#xff08;我的模板配置文件夹叫做 a-custom&#xff09;放入该文件夹下的 templates 文件夹内&am…

【欧拉函数变化】[SDOI2012] Longge 的问题

求和 gcd(i,j) 转化为 k*gcd(i/k,j/k) 1 (i,j%k 0)。 本质就是利用互质转化到了欧拉函数的领域上。 [SDOI2012] Longge 的问题 - 洛谷 转自小粉兔 #include<bits/stdc.h> #define int long long using namespace std; unordered_map<int,int>pd; long long…